A. k-Factorization(Codeforces 797A)
思路
本题入手的角度是将输入的 n 看成一系列素数(素因子)的乘积。
- 因为素因子已经是因子分解的最小单位了,所以如果
n 的素因子的数量 f 小于k 的话那么无论如何都无法表示为 k 个数相乘的形式。 - 否则可以将前
k−1 个因子构造成前 k−1 个数,将第 k 到第f 个因子的乘积构造成第 k 个数。并且这样的解必然存在。
代码
#include <bits/stdc++.h>
using namespace std;
vector <int> ans;
int n, k, f, tmp;
// 对n进行因式分解
void primeFactor(int n) {
for(int i = 2; i * i <= n; i++) {
while(n % i == 0) {
// 将素因子储存起来
ans.push_back(i);
n /= i;
}
}
if(n != 1) {
ans.push_back(n);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
primeFactor(n);
f = ans.size();
// 判断无解的情况
if(f < k) {
cout << -1 << endl;
return 0;
}
// 输出前k - 1个数
for(int i = 0; i < k - 1; i++) {
cout << ans[i] << ' ';
}
tmp = 1;
for(int i = k - 1; i < f; i++) {
tmp = tmp * ans[i];
}
// 最后一个数由最后几个素因子合成
if(tmp > 1) {
cout << tmp << endl;
}
return 0;
}
B. Odd sum(Codeforces 797B)
思路
本题的入手点是探究奇数和的构成。
我们知道,奇数和偶数有这样的性质。
- 奇数 + 奇数 = 偶数
- 奇数 + 偶数 = 奇数
- 偶数 + 偶数 = 偶数
在本题中,子序列里偶数的数量是不影响子序列和的奇偶性的。为了让子序列的和尽可能大,
我们应该将所有非负偶数都包含在子序列中,负偶数可以舍弃
那么,子序列中的奇数呢?显然,子序列中的奇数必须有奇数个。(因为题目保证一定有解所以不用考虑序列中没有奇数的情况)所以我们可以
我们可以对所有的奇数从大到小排序,先选最大的奇数加入子序列,从而保证子序列的和一定是奇数。然后成对地向子序列中加入奇数,保证子序列和的奇偶性不变。
代码
#include <bits/stdc++.h>
using namespace std;
vector <int> vec;
int n, m, num, res;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
res = 0;
for(int i = 1; i <= n; i++) {
cin >> num;
// 如果是正奇数或复奇数
if(num % 2 != 0) {
vec.push_back(num);
}
// 如果是正偶数
else if(num > 0) {
res += num;
}
}
m = vec.size();
// 排序
sort(vec.begin(), vec.end());
res += vec[m-1];
for(int i = m - 2; i > 0; i -= 2) {
// 负数就不能被加进答案了
if(vec[i] + vec[i-1] <= 0) {
break;
}
res += (vec[i] + vec[i-1]);
}
cout << res << endl;
return 0;
}
C. Minimal string(Codeforces 797C)
思路
本题的入手点在对
因为字符串 s 的首字符在不断地被加入