题面
题意
有n位工人,每位工人都只工作一天,一天只能有一个工人在工作,每个工人有一条死线,经过那一天后将不能再工作,请给出一组死线,使让每一个工人都工作的方法数为c。如有多种方案,输出所有工人死线的最大值最小的那个。
做法
由题易知:c=π(1~n)(d[i]-i+1),d[i]<=d[i+1].
因此可以发现的d[n]做出的贡献不一定是最大的(样例就体现了这一点),也可以发现d[n]做出的贡献一定是c的一个因数,因此,我们可以暴力枚举d[n]做出的贡献,然后贪心的让n-1,n-2…..1做出的贡献最大,即可得出最优解。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 1001000
using namespace std;
int T,n,c,t,last,ans[N],aa,yz[N],yy;
int main()
{
int i,j,k;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&c);
yy=0;
for(i=1;i*i<=c;i++)
{
if(c%i==0)
{
yz[++yy]=i;
if(i*i!=c)
yz[++yy]=c/i;
}
}
sort(yz+1,yz+yy+1);
for(i=1;i<=yy;i++)
{
t=c,aa=0;
for(j=n,k=i;j>=1&&k>=1&&t>1;j--)
{
for(;k>=1;k--)
{
if(t%yz[k]==0) break;
}
if(!k) break;
t/=yz[k];
ans[++aa]=yz[k];
if(t%(yz[k]+1)==0) k++;
}
if(t==1)
{
for(j=1;j<=n-aa;j++) printf("%d ",j);
for(j=n-aa+1,k=aa;j<=n,k>=1;j++,k--) printf("%d ",ans[k]+j-1);
puts("");
break;
}
}
}
}