CodeForces

来源:互联网 发布:单片机识别条形码 编辑:程序博客网 时间:2024/06/04 18:46

Maximal GCD

题目传送门
题意:给你两个数n,k。要你找一个严格连续递增数列,要求序列有k个元素,和为n并且gcd最大。
思路:很容易知道,要使得gcd最大,那么最大公约数必为数列首项,所以其最大公约数一定是n的因子。最好的情况为1d,2d,3d……,kd(d为最大公约数),即有 k*(k+1)/2 个d。因此,我们只需要求出n的因子,找到小于等于n/k*(k+1)/2中最大的因子就是最优的d,然后按照1d,2d,3d……,xd凑出数列即可。

#include <iostream>#include <fstream>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <cmath>#include <algorithm>#include <functional>#define inf 10000000using namespace std;typedef long long ll;const int MAXN=5e6+10;const int MAX=1e6+10;const double eps=1e-6;ll n,k;ll s[MAX];int main(){    #ifdef ONLINE_JUDGE    #else    freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    #endif    cin>>n>>k;    if((double)(k+1)>(double)(2*n/k)){        cout<<-1<<endl;        return 0;    }    int cnt=1;    for(int i=1;i<=sqrt(n);i++){        if(n%i==0)            s[cnt++]=i,s[cnt++]=n/i;    }    sort(s+1,s+cnt+1);    ll d=2*n/(k*(k+1));    for(int i=cnt-1;i>=1;i--){        if(s[i]<=d){            d=s[i];            break;        }    }    ll sum=0;    for(ll i=1;i<=k;i++){        if(i==k){            printf(" %lld\n",n-sum);            return 0;        }        sum+=i*d;        if(i==1)    printf("%lld",i*d);        else    printf(" %lld", i*d);    }    return 0;}
原创粉丝点击