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 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
题目大意:给定数N ,K,P 求是否有这样的K个数(可重复)使得这些数的P次方相加之和等,若有(可能有多个)则求出这样一个递减数列a,使得1≤L≤K and i<L,ai==bi aL>bL ,否则输出“Impossible”。
思路: 1.由于此题N<=400数据量较小,且重复同一个操作,即不断的加某一个数的平方并验证是否等于N,所以可选择用深度搜索算法。(普通深度搜索会造成有一个样例超时)
2.首先用一个数组num将平方在[0,N]之间的数存储,num[i]对应存储i的平方数。
3.开始深搜,首先创建一个K个空间的数组temp,它用来存储每一次深搜过程中加的数i,用sum来求i的平方的和,
4.用tempMax来存储深搜过程中所加i的总和(原因:筛选出符合题意的那个数列,即最小的数 最大那个数列),由于是从num.size()-1开始深搜,所以如果b数列的tempMax小于a数列的tempMax的话,一定有a[L]>b[L]。(如果不判断,有一个测试样例会答案错误)。
5,如果用普通深搜,每一次都从0开始遍历,将会超时,因此可以剪枝,因为输出数列是降序,所以如果我们第层递归为第i个数,那么下一层递归就从第i个数开始,这样可以把计算量缩小一半。
坑点:1.筛选满足题意的数列,第L位最大的数列不一定位满足要求的数列,还必须满足前提a[i]==b[i] 。因此利用递减数列求和比较可以筛选出(思路的第3点)
2.必须裁剪递归树,否则会超时(思路 第3点)。
感谢:感谢柳婼大佬的博客,让我发现自己 筛选出符合题意的数列的思维漏洞。
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
vector<int>result;
int n, k, p,Max=0;
//递归
void DFS(vector<int>&temp, vector<int>&num, int deep, int sum, int i,int tempMax) {
//每一层加入一个数,在第K层时判断是否更新result最终数组
if (deep == k) {
if (sum == n && Max<tempMax) {
result.assign(temp.begin(), temp.end());
}
return;
}
for (; i >=1; i--) {
//递归满足的条件
if (sum +num[i] <= n){
temp[deep]=i;
DFS(temp, num, deep + 1, sum + num[i], i,tempMax+num[i]);
}
}
}
int main() {
cin >> n >> k >> p;
vector<int>num;
num.push_back(0);
//输入数列,第num[i]对应i的平方
for (int i = 1; pow(i, p) <= n; i++) {
num.push_back(pow(i,p));
}
vector<int>temp(k,0);//用来暂时存储记录的数字i
result.resize(k,0);//最终结果数列
DFS(temp, num, 0, 0,num.size()-1);//递归深搜
//输出
if (result[k-1] == 0) {
cout << "Impossible" << endl;
}
else {
printf("%d = ", n);
for (int i = 0; i<result.size(); i++) {
if (i != 0) printf(" + ");
printf("%d^%d", result[i], p);
}
}
}