洛谷Maximal GCD

题意翻译

请你构造一个长度为 kk 的严格上升正整数序列,使得所有数的和恰好为 nn,并且所有数的最大公约数最大。输出这个序列。如果没有合法的序列输出 -1−1。如果有多个合法的序列,可以输出任意一个。

1\le n,k\le 10^{10}1≤n,k≤1010

本题思路

留意序列的最大公约数必定是n的一个因子,假设为d
所以题目可以转化为:寻找一个最大的因子d,使得
1d + 2d + 3d + ... + (k - 1)d <= n (如果不是等于而是小于的时候,我们把剩余的数全部堆到序列最后一项即可)
所以关键是求出n的所有因子,然后从大到小搜索,找到第一个满足条件的d之后构造答案即可

算法步骤
1 输入n, k 
2 计算 m = k * (1 + k) / 2
3 求出n的所有因子并从大到小排序保存到数组fac中
4 For d: fac
5 if n / d >= m:
6 ans=[1d, 2d, 3d, ... kd]
7 ans[last] = n - sum(ans[1..k-1]) // 把剩余的数全部放到ans最后一项
8 输出ans
(以上算法未包含答案为-1的情况,请自行补充)

代码:

#include <bits/stdc++.h>

#define ll long long

namespace std;

signed main()

{

    ll n,k,m;

    cin>>n>>k;

    m=k*(k+1)/2;

    if(m>n)

{

    cout<<"-1";

    return 0;

}

    int str=0;

    for(ll i=1;i*i<=n;i++)

    {

        if(n%i==0)

        {

    if(m<=i)

    {

        str=max(str,n/i);

    }

    if(m<=n/i)
    {
    str=max(str,i);

    }}}

    n/=str;

    for(ll i=1;i<k;i++)

    {

    cout<<i*str<<" ";

    n-=i;

    }

    cout<<n;

    return 0;

}

这道题问题所在于有很多样例,所以有些样例的数字很大,一般的int,不能很好的表示,需要用到long long,如何提高数据的存储效率跟运行速度也是编程关键所在。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值