周末训练笔记(10.8)—hdu3016+poj2886
来源:互联网 发布:windows c盘清理 编辑:程序博客网 时间:2024/05/20 10:10
国庆假期过得还真快啊,感觉还没干啥就又回来了,树状数组的题目刷的差不多了(题目不一一发了),扫扫尾就结束了,“沉迷”于线段树“无法自拔”,个人感觉线段树好用一些,线段树的耗费空间是大了些,但是以空间换时间还是很划算的,最重要的是适用范围广,各有各的优点吧。
——补上几道思维题。
Man Down
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 17 Accepted Submission(s) : 8
http://hi.baidu.com/abcdxyzk/blog/item/16398781b4f2a5d1bd3e1eed.html
We take a simplified version of this game. We have only two kinds of planks. One kind of the planks contains food and the other one contains nails. And if the man falls on the plank which contains food his energy will increase but if he falls on the plank which contains nails his energy will decrease. The man can only fall down vertically .We assume that the energy he can increase is unlimited and no borders exist on the left and the right.
First the man has total energy 100 and stands on the topmost plank of all. Then he can choose to go left or right to fall down. If he falls down from the position (Xi,Yi),he will fall onto the nearest plank which satisfies (xl <= xi <= xr)(xl is the leftmost position of the plank and xr is the rightmost).If no planks satisfies that, the man will fall onto the floor and he finishes his mission. But if the man’s energy is below or equal to 0 , he will die and the game is Over.
Now give you the height and position of all planks. And ask you whether the man can falls onto the floor successfully. If he can, try to calculate the maximum energy he can own when he is on the floor.(Assuming that the floor is infinite and its height is 0,and all the planks are located at different height).
410 5 10 105 3 6 -1004 7 11 202 2 1000 10
140
思路:这个题目的处理挺巧妙的,夹杂着dp,主要的一点就是以木板的长度建树,然后开始覆盖,上面的木板覆盖下面的木板。这样的目的在于快速的确定下一步可以走动的木板。
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define N 100010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int tree[N<<2];struct node{ int lx,rx,val; int h;}map[100010];bool cmp(node a,node b){ return a.h<b.h; }int lid[N],rid[N],dp[N];void build(int l,int r,int rt){ tree[rt]=0; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson);}int id;void update(int &L,int &R,int l,int r,int rt){ if(L<=l&&R>=r) { tree[rt]=id; return; } if(tree[rt]!=-1) { tree[rt<<1]=tree[rt<<1|1]=tree[rt]; tree[rt]=-1; } int m=(l+r)>>1; if(L<=m) update(L,R,lson); if(R>m) update(L,R,rson);}int query(int index,int l,int r,int rt){ if(tree[rt]!=-1) return tree[rt]; int m=(l+r)>>1; if(index<=m) return query(index,lson); return query(index,rson);}int main(){ int n; int i,k; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); k=0; for(i=1;i<=n;i++) { scanf("%d%d%d%d",&map[i].h,&map[i].lx,&map[i].rx,&map[i].val); if(map[i].rx>k) k=map[i].rx; } sort(map+1,map+n+1,cmp); build(1,k,1); for(i=1;i<=n;i++) { lid[i]=query(map[i].lx,1,k,1); rid[i]=query(map[i].rx,1,k,1); id=i; update(map[i].lx,map[i].rx,1,k,1); } dp[n]=100+map[n].val; for(i=n;i>=1;i--) if(dp[i]>0) { dp[lid[i]]=max(dp[lid[i]],dp[i]+map[lid[i]].val); dp[rid[i]]=max(dp[rid[i]],dp[i]+map[rid[i]].val); } if(dp[0]>0)printf("%d\n",dp[0]); else cout<<-1<<endl; } return 0; }
Who Gets the Most Candies?
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 262144/131072K (Java/Other)
Total Submission(s) : 28 Accepted Submission(s) : 11
N children are sitting in a circle to play a game.
The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (−A)-th child to the right.
The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p. Who gets the most candies?
4 2Tom 2Jack 4Mary -1Sam 1
Sam 3
#include<iostream>#include<string.h>#include<stdio.h>#define lson l,m ,rt<<1#define rson m+1,r,rt<<1|1#define maxn 500010using namespace std;char name[maxn][12];int num[maxn];int rprim[35][2]={ 498960,200,332640,192,277200,180,221760,168,166320,160, 110880,144,83160,128,55440,120,50400,108,45360,100, 27720,96,25200,90,20160,84,15120,80,10080,72, 7560,64,5040,60,2520,48,1680,40,1260,36, 840,32,720,30,360,24,240,20,180,18, 120,16,60,12,48,10,36,9,24,8, 12,6,6,4,4,3,2,2,1,1 };int tree[maxn<<2];int n,k;void pushup(int rt){ tree[rt]=tree[rt<<1]+tree[rt<<1|1];}void bulid(int l,int r,int rt){ if(l==r){ tree[rt]=1; return ; } int m=(l+r)/2; bulid(lson); bulid(rson); pushup(rt);}void update(int p,int add,int l,int r,int rt){ if(l==r){ tree[rt]=add; k=l; return ; } int m=(l+r)>>1; if(p<=tree[rt<<1])update(p,add,lson); else update(p-tree[rt<<1],add,rson); pushup(rt);}int query(int L,int R,int l,int r,int rt){ if(L<=l && r<=R){ return tree[rt]; } int m=(l+r)>>1; int ret=0; if(L<=m)ret+=query(L,R,lson); if(R>m)ret+=query(L,R,rson); return ret;}int main(){ while(cin>>n>>k) { int p=0; while(n<rprim[p][0]) p++; int x=rprim[p][0]; bulid(1,n,1); for(int i=1;i<=n;i++) scanf("%s %d",name[i],&num[i]); int m=n; int now=k; for(int i=1;i<x;i++) { update(now,0,1,n,1); m--; if(num[k]%m==0) { if(num[k]>0)num[k]=m; else num[k]=1; } else{ num[k]%=m; if(num[k]<0) num[k]+=m+1; } int left=query(1,k,1,n,1); int right=m-left; if(num[k]<=right) { now=left+num[k]; }else{ now=num[k]-right; } } update(now,0,1,n,1); cout<<name[k]<<" "<<rprim[p][1]<<endl; } return 0;}
小明系列问题——小明序列
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 48 Accepted Submission(s) : 25
提起小明序列,他给出的定义是这样的:
①首先定义S为一个有序序列,S={ A1 , A2 , A3 , ... , An },n为元素个数 ;
②然后定义Sub为S中取出的一个子序列,Sub={ Ai1 , Ai2 , Ai3 , ... , Aim },m为元素个数 ;
③其中Sub满足 Ai1 < Ai2 < Ai3 < ... < Aij-1 < Aij < Aij+1 < ... < Aim ;
④同时Sub满足对于任意相连的两个Aij-1与Aij都有 ij - ij-1 > d (1 < j <= m, d为给定的整数);
⑤显然满足这样的Sub子序列会有许许多多,而在取出的这些子序列Sub中,元素个数最多的称为“小明序列”(即m最大的一个Sub子序列)。
例如:序列S={2,1,3,4} ,其中d=1;
可得“小明序列”的m=2。即Sub={2,3}或者{2,4}或者{1,4}都是“小明序列”。
当小明发明了“小明序列”那一刻,情绪非常激动,以至于头脑凌乱,于是他想请你来帮他算算在给定的S序列以及整数d的情况下,“小明序列”中的元素需要多少个呢?
2 01 25 13 4 5 1 25 23 4 5 1 2
221
#include<iostream>#include<stdio.h>#include<string.h>using namespace std;int a[100010],dp[100010],c[100010];int n,k;int bin(int t){ int l=1,r=n; while(l<=r) { int mid=(l+r)/2; if(t>c[mid]) l=mid+1; else r=mid-1; } return l;}int solve(){ int ans=0; for(int i=1;i<=n;i++) { dp[i]=bin(a[i]); if(dp[i]>ans) ans=dp[i]; int j=i-k; if(j>0&&c[dp[j]]>a[j]) c[dp[j]]=a[j]; } return ans;}int main(){ while(cin>>n>>k) { memset(c,0x3f3f3f3f,sizeof(c)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } printf("%d\n",solve()); } return 0;}
- 周末训练笔记(10.8)—hdu3016+poj2886
- 周末训练笔记(二)
- 周末训练笔记(三)
- 周末训练笔记(四)
- 周末训练笔记(10.1)
- 周末训练笔记
- 周末训练笔记+hdu1255+4288
- 周末训练笔记+I Hate It(9.3)
- 周末训练笔记+hdu1576 A/B
- 周末训练笔记+UVA11388+POJ2407+无名题
- 周末训练笔记+Uva10912+10994+POJ1006
- 周末训练笔记+数论主要知识点
- 周末训练笔记+HDU1205+POJ1306【排列组合】
- hdu3016——Man Down
- 周末训练笔记+2017 ACM/ICPC Asia Regional Shenyang Online(9.10)
- 周末训练笔记+2017 ACM/ICPC Asia Regional Qingdao+Xian Online(9.17)
- poj2886
- poj2886
- HTML轮播记住一定要导入两个包
- 自定义view自定义一个带箭头的圆形详解 加速 减速 变颜色
- Java连接数据库DBHelper增删改查[多条数据]
- java String stringbuilder stringbuffer
- qbxt国庆水题记day2
- 周末训练笔记(10.8)—hdu3016+poj2886
- 《个人理财》
- Android开发艺术探索__android动画深入分析(七)
- 当鼠标悬停在时,改变字体,旋转,
- 电脑网线水晶头接法图解
- 盒子模型
- UVALive-7267/UVALive-7261/UVALive-7269/UVALive-7263
- reflow&repaint
- 关于用户管理的练习