• NOIP 2016蚯蚓(优先队列)


    85分做法:

    利用优先队列找出最大的蚯蚓,再用懒标记去计算增长的长度即可( 除了那被切成的两只蚯蚓其他的都往正方向移动了一些, 等价于那两只往负方向移动了一些. 所以可以记录累计加的长度, 有几只没被加的就减去就好了)

    #include<queue>
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxm=1e5+7;
    int n,m,q,u,v,t;
    double p;
    int a[maxm];
    priority_queue<int > qq;
    int grow=0;//总共增长的长度 
    int main()
    {
     scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
     for(int i=1;i<=n;i++)
     scanf("%d",&a[i]),qq.push(a[i]);
     p=(double)u/v;
     for(int i=1;i<=m;i++)
     {
      int top=qq.top()+grow;
      qq.pop();
      int a1=floor((double)top*p),a2=top-a1;
      grow+=q;
      a1-=grow;
      a2-=grow;//保证下次加grow的值为本身 
      qq.push(a1),qq.push(a2);
      if(i%t==0)
      printf("%d ",top);
     }
     printf("
    ");
     for(int i=1;i<=n+m;i++)
     {
       int top=qq.top()+grow;
       qq.pop();
       if(i%t==0)
       {
            printf("%d ",top);
       }
     }
     return 0;    
    }

    满分做法:

    发现先被切掉的蚯蚓分成的蚯蚓一定比后切掉的蚯蚓分成的蚯蚓大,所以直接数组存储即可。

    #include<queue>
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxm=7e6+7;
    int n,m,q,u,v,t;
    double p;
    int a[maxm];
    int grow=0;//总共增长的长度 
    int now[maxm],cut1[maxm],cut2[maxm];
    int h,h1,h2,t0,t1,t2;
    int top;
    int flag;
    bool cmp(int a,int b)
    {
     return a>b;    
    }
    int main()
    {
     scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
     for(int i=1;i<=n;i++)
     scanf("%d",&now[i]);
     p=(double)u/(double)v;
     h=h1=h2=1;
     t0=n;
     t1=t2=0;
     sort(now+1,now+n+1,cmp);
     for(int i=1;i<=m;i++)
     {
       top=-2e9+7;
       flag=0;
       if(h<=t0&&now[h]>top) top=now[h],flag=1;
       if(h1<=t1&&cut1[h1]>top) top=cut1[h1],flag=2;
       if(h2<=t2&&cut2[h2]>top) top=cut2[h2],flag=3;
       if(flag==1)
       h++;
       if(flag==2)
       h1++;
       if(flag==3)
       h2++;
       top+=grow;
       int a1=floor((double)top*p),a2=top-a1;
       grow+=q;
       a1-=grow,a2-=grow;
       cut1[++t1]=a1,cut2[++t2]=a2;
       if(i%t==0)
       printf("%d ",top);
     }
     printf("
    ");
     for(int i=1;i<=n+m;i++)
     {
          top=-1e9+7;
          flag=0;
         if(now[h]>top&&h<=t0) top=now[h],flag=1;
         if(cut1[h1]>top&&h1<=t1) top=cut1[h1],flag=2;
         if(cut2[h2]>top&&h2<=t2) top=cut2[h2],flag=3;
         if(flag==1)
         h++;
         if(flag==2)
         h1++;
         if(flag==3)
         h2++;
          if(i%t==0)
          {
           printf("%d ",top+grow);    
         }
     }
     return 0;    
    }
  • 相关阅读:
    【搞笑】各种程序评测结果
    【UVA】P1510 Neon Sign
    【转载】实用:根号怎么打出来? <引自百度>
    【转载】C++中的模板template <typename T>
    * ! THUSC2017杜老师
    * ! THUSCH2017巧克力
    ! BJOI2019光线
    ! BJOI2019奥术神杖
    ! TJOI/HEOI2016字符串
    ! TJOI/HEOI2016求和
  • 原文地址:https://www.cnblogs.com/lihan123/p/11741828.html
Copyright © 2020-2023  润新知