1. 程式人生 > >【NOIP】提高組2016 蚯蚓

【NOIP】提高組2016 蚯蚓

one noi -i splay pla uoj 過程 etc closed

【題目鏈接】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; }
View Code

【NOIP】提高組2016 蚯蚓