【NOIP】提高组2016 蚯蚓
【题目链接】Universal Online Judge
【题解】本题最大的特点在于从大到小切以及切分规则一致,都是切成px和x-px。
由这两个特点很容易得到结论,后切的蚯蚓得到的px一定比先切的蚯蚓得到的px小,后切的蚯蚓得到的x-px一定比先切的蚯蚓得到的x-px小。
所以可以得到三队列做法,将原蚯蚓排序后放入A队列,将每次切分后的px放入B队尾,x-px放入C队尾。每次从ABC三队头取较大者弹出并切分,将切分后的蚯蚓放入BC队尾,整体+q转化为单点-q即可。
注意:UOJ extra test卡精度,可以将u/v直接带入主过程,就不用计算p了。
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cctype> using namespace std; const int maxn=100010; int read(){ char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c=='-')t=-1; do{s=s*10+c-'0';}while(isdigit(c=getchar())); return s*t; } queue<int>A,B,C; int n,m,q,u,v,t,a[maxn]; int main(){ n=read();m=read();q=read();u=read();v=read();t=read(); for(int i=1;i<=n;i++)a[i]=read(); sort(a+1,a+n+1); for(int i=n;i>=1;i--)A.push(a[i]); for(int i=1;i<=m;i++){ if(!A.empty()&&(A.front()>=B.front()||B.empty())&&(A.front()>=C.front()||C.empty())){ int x=A.front()+(i-1)*q;A.pop();if(i%t==0)printf("%d ",x); B.push((int)(1ll*x*u/v)-i*q);C.push(x-(int)(1ll*x*u/v)-i*q); } else if(!B.empty()&&(B.front()>=C.front()||C.empty())){ int x=B.front()+(i-1)*q;B.pop();if(i%t==0)printf("%d ",x); B.push((int)(1ll*x*u/v)-i*q);C.push(x-(int)(1ll*x*u/v)-i*q); } else{ int x=C.front()+(i-1)*q;C.pop();if(i%t==0)printf("%d ",x); B.push((int)(1ll*x*u/v)-i*q);C.push(x-(int)(1ll*x*u/v)-i*q); } } printf("\n"); for(int i=1;i<=n+m;i++){ if(!A.empty()&&(A.front()>=B.front()||B.empty())&&(A.front()>=C.front()||C.empty())){ int x=A.front()+m*q;A.pop();if(i%t==0)printf("%d ",x); } else if(!B.empty()&&(B.front()>=C.front()||C.empty())){ int x=B.front()+m*q;B.pop();if(i%t==0)printf("%d ",x); } else{ int x=C.front()+m*q;C.pop();if(i%t==0)printf("%d ",x); } } printf("\n"); return 0; }