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("\n");
 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("\n");
 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;    
}

猜你喜欢

转载自www.cnblogs.com/lihan123/p/11741828.html