关闭

TJU-4107. A simple problem(贪心)

标签: acm贪心tuj
214人阅读 评论(0) 收藏 举报
分类:
Given three integers n(1n1018),m(1m105),k(1k1018). you should find a list of integer A1,A2,,Am which satisfies three conditions:
1. A1+A2++Am=n.
2. 1Aik1 for each (1im).
3. GCD(A1,A2,,Am)=1.GCD means the greatest common divisor
4. if i<jthenAiAj.

As the author is too lazy to write a special judge, if there's no answer ouput "I love ACM", And if there's more than one answer, output the one has the minimumA1, and if there still multiple answer make the A2 as small as possible, then A3,A4


主要思想:

把n先均分成m份,多余的分摊到前面。如果数列存在两个相差1的数,那么这个数列整体的GCD为1.

这里有好多特殊情况要处理,比如m=1,m=2,n=m等等等。

比如

10 2 10

10 10 3

10 5 3

2 1 2

1 1 3

ps:TJU的数据很弱,队友丢了情况都过了......

自己有一处判断加上去之后就WA,不知道为什么。

#include<cstdio>
#include<cstring>
#define imp {printf("I love ACM\n"); return;}
using namespace std;

long long ans[100005];

long long gcd(long a,long b)
{
    long long r;
    while(b>0)
    {
        r=a%b;
        a=b;
        b=r;
    }
    return a;
}

void work(long long n,long long m,long long k)
{
    int i,j;
    long long x,y;

   // if((m*k-m)<=n)
   //实在搞不懂为什么加上上面那句话就会WA
    if(n<m) imp
    if(n==m)
    {
        if(k<2) imp
        else
        {
            printf("1");
            for(i=2;i<=m;i++) printf(" 1");
            printf("\n");
            return ;
        }
    }
    if(m==1)
    {
        if(n!=1) imp
        if(k<=1) imp
        printf("%lld\n",n);
    }
    else if(m==2)
    {
        if((n&1)==0)
        {
            x=y=n/2;
            x++;
            y--;
            while(gcd(x,y)!=1 && x<k && y>0)
            {
                x++;
                y--;
            }
            if(gcd(x,y)!=1) imp
            if(x>=k) imp
            printf("%lld %lld\n",x,y);
        }
        else
        {
            x=y=n/2;
            x++;
            if(gcd(x,y)!=1) imp
            if(x>=k) imp
            printf("%lld %lld\n",x,y);
        }
    }
    else
    {
        for(i=1;i<=m;i++) ans[i]=n/m;
        if(n%m==0)
        {
            ans[1]++;
            ans[m]--;
            if(ans[1]>=k) imp
            for(i=1;i<m;i++) printf("%lld ",ans[i]);
            printf("%lld\n",ans[m]);
        }
        else
        {
            n-=ans[1]*m;
            i=0;
            while(n--) ans[++i]++;
            if(ans[1]>=k) imp
            for(i=1;i<m;i++) printf("%lld ",ans[i]);
            printf("%lld\n",ans[m]);

        }    
    
    }

}
int main()
{
    long long n,m,k;
    while(~scanf("%lld%lld%lld",&n,&m,&k))
        work(n,m,k);
    return 0;
}



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:23852次
    • 积分:1020
    • 等级:
    • 排名:千里之外
    • 原创:81篇
    • 转载:3篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论