zoukankan      html  css  js  c++  java
  • 洛谷P2827 蚯蚓

    传送门

    pts85/90(90应该是个意外,第一次交是90之后都是85了):

    优先队列模拟题意

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    int n,m,q,u,v,t,tim;
    double p;
    priority_queue<int>qq;
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
        p=1.0*u/(1.0*v);
        for(int i=1,x;i<=n;i++){
            scanf("%d",&x);
            qq.push(x);
        }
        while(m--){
            tim++;
            int x=qq.top();
            qq.pop();
            if(tim%t==0)printf("%d ",x+(tim-1)*q);
            int y=(int)(p*(double)(x+(tim-1)*q));
            x=(x+(tim-1)*q)-y;
            qq.push(x-tim*q),qq.push(y-tim*q);
        }
        printf("
    ");
        int now=0;
        while(qq.size()){
            now++;
            if(now%t==0){
                printf("%d ",qq.top()+tim*q);
            }
            qq.pop();
        }
        return 0;
    }
    优先队列

    顺手练一下手写二叉堆

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,m,q,u,v,t,tim,a[16*1000010],num;
    double p;
    bool cmp(int x,int y){
        return x>y;
    }
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
        p=1.0*u/(1.0*v);
        for(int i=1,x;i<=n;i++){
            scanf("%d",&a[i]);
            x=i;
            while(x>1&&a[x]>a[x>>1]){
                swap(a[x],a[x>>1]);
                x>>=1;
            }
        }
        while(m--){
            tim++;
            int x=a[1];
            if(tim%t==0)printf("%d ",x+(tim-1)*q);
            int y=(int)(p*(double)(x+(tim-1)*q));
            x=(x+(tim-1)*q)-y;
            a[1]=x-tim*q;
            int now=1;
            while((a[now]<a[now<<1]||a[now]<a[now<<1|1])&&(now<<1|1)<=n){
                if(a[now<<1]<a[now<<1|1]){
                    swap(a[now],a[now<<1|1]);
                    now<<=1;
                    now|=1;
                }
                else{
                    swap(a[now],a[now<<1]);
                    now<<=1;
                }
            }
            if(a[now]<a[now<<1]&&(now<<1)<=n){
                swap(a[now],a[now<<1]);
            }
            a[++n]=y-tim*q;
            now=n;
            while(now>1&&a[now]>a[now>>1]){
                swap(a[now],a[now>>1]);
                now>>=1;
            }
        }
        printf("
    ");
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++){
            if(i%t==0){
                printf("%d ",a[i]+tim*q);
            }
        }
        return 0;
    }
    手写二叉堆

    正解:

    发现先切的蚯蚓产生的长段永远不小于后切的蚯蚓产生的长段,短段也是。因为从准备切先切的开始,后切的生长t个单位长度的同时,先前切好的两段都生长了t-1个单位长度。

    切好的长段集合和短段集合本身就具有单调性。

    用三个队列分别储存未切的,切好的长段,切好的短段,每次从三个队头寻找最大的进行操作。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    using namespace std;
    int n,m,q,u,v,t,tim,maxx,pos,a[8*1000010],inf=214748364;
    double p;
    queue<int>qq[3];
    bool cmp(int x,int y){
        return x>y;
    }
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
        p=1.0*u/(1.0*v);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        sort(a+1,a+n+1);
        for(int i=n;i>=1;i--)qq[0].push(a[i]); 
        while(m--){
            tim++;
            maxx=pos=-inf;
            if(qq[0].front()>maxx&&qq[0].size())maxx=qq[0].front(),pos=0;
            if(qq[1].front()>maxx&&qq[1].size())maxx=qq[1].front(),pos=1;
            if(qq[2].front()>maxx&&qq[2].size())maxx=qq[2].front(),pos=2;
            qq[pos].pop();
            if(tim%t==0)printf("%d ",maxx+(tim-1)*q);
            int y=(int)(p*(double)(maxx+(tim-1)*q));
            maxx=(maxx+(tim-1)*q)-y;
            qq[1].push(max(maxx,y)-tim*q),qq[2].push(min(maxx,y)-tim*q);
        }
        printf("
    ");
        n=0;
        while(qq[0].size()){
            a[++n]=qq[0].front();
            qq[0].pop();
        }
        while(qq[1].size()){
            a[++n]=qq[1].front();
            qq[1].pop();
        }
        while(qq[2].size()){
            a[++n]=qq[2].front();
            qq[2].pop();
        }
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++){
            if(i%t==0){
                printf("%d ",a[i]+tim*q);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Apache Jmeter 性能测试
    linux 达梦数据库 命令行 卸载
    vue控制台报错Duplicate keys detected: 'xxxx'. This may cause an update error.解决方案
    springboot报错说 Failed to parse multipart servlet request; nested exception is java.io.IOException
    简单理解Callable接口
    Windows下设置Mongodb用户名密码
    Win10 搭建FTP环境,并使用Java实现上传,下载,删除
    【小组展示】1
    【计网II】
    【密码学】AES
  • 原文地址:https://www.cnblogs.com/chloris/p/11852968.html
Copyright © 2011-2022 走看看