题目链接
http://codeforces.com/contest/803/problem/C
题意
给一个数n和一个数k,要求把n分成k个数 a1,a2,...ak 的和,并且这k个数严格递增,并且使划分出来的这k个数的GCD最大,求划分方案。
思路
a1+a2+...+ak=n
假设其最大的gcd为x,那么就有:
x⋅p1+x⋅p2+...+x⋅pk=n
极端情况是
p1
到
pk
依次是
1,2,3,...,k
我们设
y=p1+p2+...+pk
,那么就有
y≥k⋅(k+1)2
如果
y>k⋅(k+1)2
,那么这k数就是:
1,2,3,...,y−(1+2+3+...+k−1)
所以,我们只需要枚举
n
的因子
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL n, k;
void print(int x) {
LL y = n / x;
for (int i = 1; i <= k - 1; i++) {
cout << x * i << ' ';
y -= i;
}
cout << x * y << endl;
exit(0);
}
int main() {
scanf("%I64d%I64d", &n, &k);
if (k >= 1e6 || (k < 1e6 && k * (k + 1) / 2 > n))
cout << -1 << endl;
else {
vector<int> v1, v2;
long long y = k * (k + 1) / 2, x = 1;
for (LL i = 1; i <= sqrt(n); i++) {
if (n % i == 0) {
v1.push_back(i);
v2.push_back(n / i);
}
}
for (int i = 0; i < v2.size(); i++) {
x = v2[i];
if (n / x >= y) {
print(x);
}
}
for (int i = v1.size() - 1; i >= 0; i--) {
x = v1[i];
if (n / x >= y) {
print(x);
}
}
}
return 0;
}

本文解析了CodeForces竞赛中一道题目C的解决方案,该题要求将一个整数n分解为k个严格递增的整数之和,并使得这些整数的最大公约数GCD尽可能大。文章详细介绍了如何通过枚举n的因子来寻找最优解的方法。
368

被折叠的 条评论
为什么被折叠?



