原题干:
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 = n1^P + ... nK^P
where ni (i=1, ... K) is the i-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
生词:
factorization : 因数分解 positive : 正的,阳性的
solution : 答案 non-increasing : 非增的
unique : 唯一的,仅有的 factor : 因子
sequence : 序列
题目大意:
给出一个数N,找到K个数,使这K个数的P次幂相加,结果等于N
如果有多种答案,则找出这k个数之和,最大的一种答案。
如果仍然有多种答案,则找出字典序最大的一种答案
这道题可以使用DFS算法解决,具体讲解在注释里讲的很清晰了,这里不做过多解释
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
/* *
* 全局变量,n为题目要求的和,k为几项,p为幂
* result为最终结果,tmp为每次的结果,table存放幂运算结果
*/
int n, k, p;
int max_result = -1;
vector<int> result, tmp, table;
/* *
* 打表,table下标的p次幂
*/
void create_table(){
int it = 1;
for(int i = 0; i <=n; i = pow(it++, p))
table.push_back(i);
}
/* *
* DFS深度优先搜索函数
* index为当前处理的数,CURRENT_N为当前幂运算后的和,CURRENT_K为当前已经处理过多少数,K_ALL_SUM为当前处理过的数的和
* "死胡同"为CURRENT_N或者CURRENT_K==k的时候。"岔道口"为继续算自己,或者处理下一个数。
* 169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
*/
void DFS(int index, int CURRENT_N, int CURRENT_K, int K_ALL_SUM){
//死胡同
if(CURRENT_N >= n || CURRENT_K == k){
if(CURRENT_N == n && K_ALL_SUM > max_result && CURRENT_K == k){
max_result = K_ALL_SUM;
result = tmp;
}
return;
}
//岔路口,index=0的时候就不能继续进行了
if(index){
//第一条路,计算自己
tmp.push_back(index);
DFS(index, CURRENT_N + table[index], CURRENT_K + 1, K_ALL_SUM + index);
//第二条路,不计算自己,计算下一个数
tmp.pop_back();
DFS(index - 1, CURRENT_N, CURRENT_K, K_ALL_SUM);
}
}
int main(){
cin >> n >> k >> p;
create_table();
DFS(table.size() - 1, 0, 0, 0);
if(max_result == -1) {
printf("Impossible");
return 0;
}
printf("%d = ", n);
for(int i = 0; i < result.size(); i++) {
if(i != 0) printf(" + ");
printf("%d^%d", result[i], p);
}
return 0;
}