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;
}