CodeChef - WRKWAYS

题面

题意

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

猜你喜欢

转载自blog.csdn.net/yzyyylx/article/details/80942347