Educational Codeforces Round 20 C(math)

本文解析了CodeForces上编号为803C的问题,该题要求将给定数值拆分为若干递增数之和,并最大化这些数的公约数。通过数学分析给出了解决方案并附带实现代码。

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

題目鏈接: http://codeforces.com/problemset/problem/803/C

 

題意: 給出兩個數n, k, 將n拆分成k個數的和,要求這k個數是嚴格遞增的,並且這k個數的gcd盡量大...

 

思路: 顯然題目的要求是求 n = a1*cnt + a2*cnt + a3*cnt..+ak*cnt 其中a1<a2<a3..<ak 並且要求cnt盡量大;

要使cnt盡量大,那麼顯然a1...ak要盡量小, 那麼可以令a1...ak=1, 2, 3, ..k, 令key=a1+a2..+ak=(1+k)*k/2;則有: n = cnt*key+y  (n不一定剛好能分下,可能多出y;

顯然有 cnt | y, 令y=cnt*z, 所以有 n=cnt*(key+z), 顯然cnt爲n滿足條件 n/cnt>=key的最大公因子, 那麼只要for一下找出cnt即可(我這裏sb了,居然一開始用二分去找cnt;

最後輸出 1*cnt, 2*cnt ...(k-1)*cnt, (n/cnt-key+k)*cnt即可...這裏的n/cnt-key爲 z;

 

代碼:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 int main(void){
 6     ll n, k, key, cnt=0;
 7     cin >> n >> k;
 8     double cc=(k+1)/2.0*k;
 9     if(cc>n){
10         cout << -1 << endl;
11         return 0;
12     }
13     key=cc;
14     for(ll i=1; i*i<=n; i++){
15         if(n%i==0){
16             if(n/i>=key) cnt=max(cnt, i);
17             if(i>=key) cnt=max(cnt, n/i);
18         }
19     }
20     for(ll i=1; i<k; i++){
21         cout << i*cnt << " ";
22     }
23     cout << (n/cnt-key+k)*cnt << endl;
24     return 0;
25 }
View Code

 

转载于:https://www.cnblogs.com/geloutingyu/p/6789766.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值