首页 > 代码库 > Educational Codeforces Round 20 C(math)

Educational Codeforces Round 20 C(math)

題目鏈接: 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

 

Educational Codeforces Round 20 C(math)