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 2Sample Output 1:
169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2Sample Input 2:
169 167 3Sample Output 2:
Impossible
计算整数幂的函数自己用循环写,否则有一个case超时,最严格的上界是upper=pow(n-s,1/double(p)),但是这个计算很慢也会超时,而且用严格的上界没有什么用,毕竟会被剪枝掉,直接用最大的上界upper=sqrt(n) 就可以了。
还有一点,就要要及时的剪枝,第二次做的时候在调用dfs前的if(cur_sum + a <= n)的时候错写成 if(cur_sum <= a)导致超时。(也不是错写,因为这样写的时候我在循环前面加了一个if(cur_sum < n)return;虽然等价,但是导致多递归调了一次,从递归调用的
解答树来看,在最后的时候多调用一层的代价很高,因为最后一层的节点太多了。所以要及时剪枝)
#include <iostream> #include <cmath> #include <vector> using namespace std; vector<int> res; vector<int> final; int n,k,p; int upper; int mypow(int e,int p){ int sum = 1; for(int i= 0;i<p;i++){ sum *= e; } return sum; } void dfs(int cur,int cur_sum){ if(cur == k+1){ if(cur_sum == n)final = res; return; } for(int i=res[cur - 1]; i<= upper;i++){ int a = mypow(i,p); if(cur_sum + a<= n){ res[cur] = i; dfs(cur + 1,cur_sum+a); }else return; } } int main(){ cin>>n>>k>>p; res.resize(k+1); res[0] = 1; upper = sqrt(n); dfs(1,0); if(final.empty() == false){ int kase = 0; printf("%d = ",n); for(int i=k;i>0;i--){ if(kase++)cout<<" + "; printf("%d^%d",final[i],p); } }else cout<<"Impossible\n"; return 0; }