【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("
");
    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("
");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/onioncyc/p/7773102.html