TJU-4107. A simple problem(贪心)

本文探讨了在给定条件下生成满足特定条件的整数序列的方法。通过细致分析和算法实现,解决了整数序列的构造问题,确保序列的和、范围、最大值以及互质性等条件得到满足。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值