hdu 4262 Juggler 这题真是跟小丑一般。。。
题意:
有个球的圈圈。三种操作:逆时针转一个,顺时针转一个,丢掉手中的那个的同时顺时针的球到你的手里。每个操作都花费一秒。告诉你要求的出圈顺序,求最小花费时间。注:开始在手中的球为1.
解:
线段树和树状数组都可。树状数组很蛋疼。建议我以后用线段树。开始为什么不用线段树是因为怕自己搞不出相对坐标和绝对坐标。凡是二分的树状数组能不写就不写。
这个是用set代替二分的代码,建议以后迫不得已要用二分的时候就用set。
/*
Pro: 0Sol:date:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#define maxn 100010
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
int n,now,c[maxn],pre,suf,alre,out,in;
__int64 ans;
struct query{int id, ord;
}q[maxn];
bool cmpx(query a,query b){return a.ord < b.ord;//ord是时间
}
int getsum(int pos){int sum = 0;while(pos){sum += c[pos];pos -= (pos & -pos);}return sum;
}
void modify(int pos){while(pos <= n){c[pos] += 1;pos += (pos & -pos);}
}
set <int> S;
set <int> :: iterator it;
int main(){while(~scanf("%d",&n) && n){memset(c,0,sizeof(c));//0 表示在手里, 1 表示已经出去了 id建边S.clear();for(int i = 1; i <= n; i ++){scanf("%d",&q[i].ord);q[i].id = i;S.insert(i);}sort(q + 1, q + n + 1, cmpx); now = 1; ans = 0; alre = 0;for(int i = 1; i <= n; i ++){// cout<<now<<" "<<q[i].id<<endl;if(now > q[i].id) {pre = q[i].id;suf = now;}else{pre = now;suf = q[i].id;}pre = pre - getsum(pre);//表示前面有多少个0,多少个还在,包括本身suf = suf - getsum(suf);in = suf - pre;out = n - alre - in;ans+=min(in,out)+1;alre ++;if(alre==n)break;S.erase(q[i].id);if(S.lower_bound(q[i].id)!=S.end()){it=S.lower_bound(q[i].id);}else{it=S.lower_bound(0);}now = *it ;}cout<<ans<<endl;}return 0;
}
这个是改出来的二分。老娘虚脱了。
/*
Pro: 0Sol:date:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#define maxn 100010
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
int n,now,c[maxn],pre,suf,alre,out,in;
__int64 ans;
struct query{int id, ord;
}q[maxn];
bool cmpx(query a,query b){return a.ord < b.ord;//ord是时间
}
int getsum(int pos){int sum = 0;while(pos){sum += c[pos];pos -= (pos & -pos);}return sum;
}
void modify(int pos){while(pos <= n){c[pos] += 1;pos += (pos & -pos);}
}
int bs(int l,int r)
{int mid,flag=l;while(l + 1< r){mid=(l+r)>>1;if(getsum(mid)-getsum(l)==mid-l){l=mid;}else{r=mid;}}if(getsum(l)-getsum(flag)==l-flag){return r;}return l;
}
int main(){while(~scanf("%d",&n) && n){memset(c,0,sizeof(c));//0 表示在手里, 1 表示已经出去了 id建边for(int i = 1; i <= n; i ++){scanf("%d",&q[i].ord);q[i].id = i;}sort(q + 1, q + n + 1, cmpx); now = 1; ans = 0; alre = 0;for(int i = 1; i <= n; i ++){if(now > q[i].id) {pre = q[i].id;suf = now;}else{pre = now;suf = q[i].id;}pre = pre - getsum(pre);//表示前面有多少个0,多少个还在,包括本身suf = suf - getsum(suf);in = suf - pre;out = n - alre - in;ans+=min(in,out)+1;alre ++;if(alre==n)break;modify(q[i].id);if(getsum(n)-getsum(q[i].id)==n-q[i].id){now= bs(0,q[i].id);//边界值问题需要处理一下}else{now= bs(q[i].id,n);}}cout<<ans<<endl;}return 0;
}
线段树代码: 其实我写过一遍类似的poj 2886,当时就是照着别人的代码敲的,还以为自己会了呢,但是发觉理解得还是不够深啊。。。别人的和自己的就是不一样啊。要把别人的学到手!!!
#include <cstdio>
#include <algorithm>
using namespace std;
#define lson l,m,rt << 1
#define rson m + 1 , r, rt <<1 | 1
#define havem int m = (l + r) >> 1
#define ls rt << 1
#define rs rt << 1 | 1
#define maxn 100100
int sum[maxn << 2];
void build(int l, int r, int rt){if(l == r){sum[rt] = 1;return ;}havem;build(lson); build(rson);sum[rt] = sum[ls] + sum[rs];
}
void update(int pos, int l, int r, int rt){if(l == r){sum[rt] = 0;return ;}havem;if(pos <= m) update(pos,lson);else update(pos,rson);sum[rt] = sum[ls] + sum[rs];
}
int query(int L,int R, int l, int r, int rt){if(L <= l && r <= R){return sum[rt];}havem;int ans = 0;if(L <= m ) ans = query(L,R,lson);if(R > m) ans += query(L,R,rson);return ans;
}
struct Qu{int id,time;bool operator < (const Qu& cmp)const{return time < cmp.time;}
}q[maxn];
int getpos(int pos, int l, int r, int rt){//去找从1开始的第pos个人,如果pos这个地方就有人,那么就是他了if(l == r) return l;havem;if(pos <= sum[ls])return getpos(pos,lson);return getpos(pos - sum[ls],rson);
}
int n;
int main(){while(~scanf("%d",&n) && n){build(1,n,1);for(int i = 1; i <= n; i ++){scanf("%d",&q[i].time);q[i].id = i;}sort(q + 1, q + 1 + n);int& mod = sum[1];//int now = 1;__int64 ans = 0;for(int i = 1; i <= n; i ++){int tmp;if(now == q[i].id){ans += 1;}else if(now < q[i].id){tmp = query(now + 1,q[i].id,1,n,1);ans += min(tmp,mod - tmp) + 1;}else{tmp = query(q[i].id,now - 1,1,n,1);ans += min(tmp,mod - tmp) + 1;}update(q[i].id,1,n,1);int Left = query(1,q[i].id,1,n,1);if( Left < mod ){//左边小于剩下的人数,说明右边有人,就去右边找now = getpos(Left + 1,1,n,1);//去找剩下的Left+1个人}else{//从后面找第一个1now = getpos(1,1, n, 1);}}printf("%I64d\n",ans);}return 0;
}
hdu 4262 Juggler 这题真是跟小丑一般。。。相关推荐
- HDU 4262 Juggler
http://acm.hdu.edu.cn/showproblem.php?pid=4262 树状数组更新点的位置,并可以求出两点之间的有多少球 View Code 1 #include <st ...
- HDU 4262 Juggler (模拟+线段树优化)
转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove http://acm.hdu.e ...
- TOJ 4354 HDU 4262 Juggler / 树状数组
Juggler 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte 描述 As part of my magical juggling act, I ...
- HDU 4262 Juggler 树状数组
将每个球按输入顺序编号,建立 它第几个被扔掉->编号 的映射关系. 记录当前在手里的球的编号,按扔掉的顺序查找这个球的编号,看看这个球是逆时针转到手里更近还是顺时针转到手里更近,即当前扔掉球的编 ...
- hdu 4262 Juggler(树状数组)
题意:某人手上有一串珠子,顺时针编号1--n,每次可进行三种操作:顺时针旋转一个珠子,逆时针旋转一个珠子,将手中的珠子移去(移去后顺时针方向下一个珠子进入手中),问按标号12345顺序将所有珠子逐一移 ...
- HDU 5703 Desert 水题 找规律
HDU 5703 Desert 水题 找规律 已知有n个单位的水,问有几种方式把这些水喝完,每天至少喝1个单位的水,而且每天喝的水的单位为整数.看上去挺复杂要跑循环,但其实上,列举几种情况之后就会发现 ...
- HDU OJ 动态规划46题解析
Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢 ...
- HDU 4121 Xiangqi 模拟题
题目: http://acm.hdu.edu.cn/showproblem.php?pid=4121 首先对标题赞一个,非要叫 "Xiangqi" 而不是 "中国象棋&q ...
- hdu 5710 Digit-Sum (构造题)
题目链接:hdu 5710 Digit-Sum 题意: 定义S(n)=n的数位和,给你一个a,b让你找一个n使得a*S(n)=b*S(2n). 题解: 传送门 构造题很少做啊!! 太弱了 1 #inc ...
最新文章
- 一笔画问题【数据结构-图论】
- CString的部分实现剖析
- ML之MaL: 流形学习MaL的概念认知、算法分类、案例应用、代码实现之详细攻略
- 2014年考研计算机大纲解析:数据结构,2014年考研计算机大纲解析之数据结构
- 山寨今日头条的标题title效果
- iOS开发之打包上传报错: ERROR ITMS-90087/ERROR ITMS-90125
- Spring核心系列之ApplicationContext
- php break foreach_PHP foreach()跳出本次或当前循环与终止循环方法
- zookeeper版本更新_zookeeper介绍及运维实践
- 通过u盘装window7
- Sql Server 2005跨数据查询
- python 操作目录注意事项
- 简介几种负载均衡原理
- 我的世界观【文津图书奖获奖作品】
- Windows中解压Linux中产生的tar.gz分卷压缩包
- 封装继承多态_继承重写重载
- matlab一维数组操作,Matlab创建一维数组的具体操作讲解
- Win 10系统自动备份文件
- linux 创建一个数据库,Linux下手动创建一个数据库
- 全球与中国湿式剃须刀市场深度研究分析报告