1103 Integer Factorization (30分)
The K−P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K−P factorization of N for any positive integers N, K and P.
Input Specification:
Each input file contains one test case which gives in a line the three positive integers N (≤400), K (≤N) and P (1<P≤7). The numbers in a line are separated by a space.
Output Specification:
For each case, if the solution exists, output in the format:
N = n[1]^P + ... n[K]^P
where
n[i]
(i
= 1, ...,K
) is thei
-th factor. All the factors must be printed in non-increasing order.Note: the solution may not be unique. For example, the 5-2 factorization of 169 has 9 solutions, such as 122+42+22+22+12, or 112+62+22+22+22, or more. You must output the one with the maximum sum of the factors. If there is a tie, the largest factor sequence must be chosen -- sequence { a1,a2,⋯,aK } is said to be larger than { b1,b2,⋯,bK } if there exists 1≤L≤K such that ai=bi for i<L and aL>bL.
If there is no solution, simple output
Impossible
.Sample Input 1:
169 5 2
Sample Output 1:
169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
Sample Input 2:
169 167 3
Sample Output 2:
Impossible
学习:https://blog.csdn.net/qq_33657357/article/details/82346814
题目大意:
给出一个数n,一个数k,一个指数p,要求你求出k个数的p次方之和为n,这k个数可以重复,如果有不同的解决方案,那么按照这k个数之和最大的情况为最优方案输出,大数在前,小数在后
解题思路:
典型的DFS,递归的边界是p次方和为n,且已经选择了k个数,注意这里的数是可以重复的,所以递归的下一层不能简单的把index进行变化,由于这里的输出要求,所以我们不从1开始遍历,我们从最大的可能数,也就是n本身开始,这样可以省去排序时间,降低时间复杂度。
递归方式1:
#include <bits/stdc++.h>
using namespace std;
int n, k, p;
int maxn = -1, f = 0;
vector<int> v, temp, ans;
void init()
{
int tmp = 0;
for (int i = 0; tmp <= n; i++) {
tmp = round(pow(i, p));
v.push_back(tmp);
}
}
void dfs(int sum, int step, int s)
{
if (sum > n)
return;
if (step == k && sum == n) {
if (s > maxn) {
maxn = s;
ans = temp;
}
return;
}
int end = temp.empty() ? v.size() - 1 : temp.back();
for (int i = end; i >= 1; i--) {
sum += v[i];
s += i;
temp.push_back(i);
dfs(sum, step + 1, s);
temp.pop_back();
s -= i;
sum -= v[i];
}
}
int main()
{
scanf("%d%d%d", &n, &k, &p);
init();
dfs(0, 0, 0);
if (ans.empty()) {
printf("Impossible\n");
return 0;
}
printf("%d = ", n);
for (int i = 0; i < k; i++) {
printf("%d^%d%s", ans[i], p, i == k - 1 ? "\n" : " + ");
}
system("pause");
}
递归方式2:
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
int left, right;
} root[10];
int n, k, p;
int maxn = -1, f = 0;
vector<int> v, temp, ans;
void init()
{
int tmp = 0;
for (int i = 0; tmp <= n; i++) {
tmp = round(pow(i, p));
v.push_back(tmp);
}
}
void dfs(int cur, int step, int sum, int s)
{
if (step == k && sum == n) {
f = 1;
if (s > maxn) {
maxn = s;
ans = temp;
}
return;
}
if (sum > n || step > k)
return;
if (cur > 0) {
temp.push_back(cur);
if (sum + v[cur] <= n) //剪枝
dfs(cur, step + 1, sum + v[cur], s + cur);
temp.pop_back();
dfs(cur - 1, step, sum, s);
}
}
int main()
{
scanf("%d%d%d", &n, &k, &p);
init();
dfs(v.size() - 1, 0, 0, 0);
if (!f) {
printf("Impossible\n");
return 0;
}
printf("%d = ", n);
for (int i = 0; i < k; i++) {
printf("%d^%d%s", ans[i], p, i == k - 1 ? "\n" : " + ");
}
system("pause");
}