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 belarger 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
题目大意
给一个正整数N(<=400),表示成K个正整数的P幂次形式(N = n1^P + ... nK^P,1<P<=7)。
要求:1、输出多项式的底数ni为非递增序列。
2、表示成的多项式如果有多个,选择底数ni和最大的一个。
3、如果多项式还有多个,比如序列{ a1, a2, ... aK }和序列{ b1, b2, ... bK },两个序列同时从左到右扫描,比较ai和bi的大小,当遇到第一个i使得ai>bi则,定义序列{ a1, a2, ... aK }比较大;当遇到第一个i使得ai<bi则,定义序列{ b1, b2, ... bK }比较大。
4、如果不存在这样的多项式,则输出“Impossible”。
题目解析
分析:题目中P最小为2,而N<=400,当ni>20时,ni^P肯定大于400,因此只需考虑(1~20)的(2~7)次方即可,这些数可以先打表存到数组里直接调用。
接下来深搜:底数从最大的数20开始搜,用vector或数组保存每次搜的底数,搜到多项式的次数为K个为止。接下来比较当前多项式的和是否等于n,并且比较当前底数的和是否比较大,若都成立就更新答案。
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
const int MAXN = 400 + 5;
const int MAXM = 100000 + 5;
const int INF = 0x7f7f7f7f;
const int dir[][2] = {0,1,1,0,0,-1,-1,0};
template <class XSD> inline XSD f_min(XSD a, XSD b) { if (a > b) a = b; return a; }
template <class XSD> inline XSD f_max(XSD a, XSD b) { if (a < b) a = b; return a; }
bool cmp(int x, int y){return x>y;}
int n, k, p;
int bef[22][9];/// 2-20 1-7
void Init(){///提前打表(1~20)^(1~7)
for(int i=1; i<=20; i++) bef[i][1] = i;
for(int i=1; i<=20; i++){
for(int j=2; j<=7; j++)
bef[i][j]=bef[i][j-1]*i;
}
}
void Getdata(){
}
int maxsum;
vector<int>ans, test;
void Dfs(int sum, int sumi, int ki, int beg){///总和 底数和 当前个数 前一个底数
if(ki==0){
if(sum==n && sumi>maxsum){///多项式和是否等于n && 底数和是否比原先成立的多项式更大
ans.clear();///清空上一次的答案
maxsum=sumi;
for(int i=0; i<test.size(); i++)///更新这一次搜的结果
ans.push_back(test[i]);
}
return;
}
if(sum>=n) return;
for(int i=beg; i>=1; i--){///底数是递减的,所以从上一次搜的数开始搜
test.push_back(i);
Dfs(sum+bef[i][p], sumi+i, ki-1, i);
test.pop_back();
}
return;
}
void Solve(){
maxsum=0;
ans.clear();
test.clear();
Dfs(0, 0, k, 20);
if(ans.empty()) printf("Impossible\n");
else{
printf("%d = ", n);
for(int i=0; i<ans.size(); i++)
printf("%d^%d%s", ans[i], p, i==(ans.size()-1)?"\n":" + ");
}
}
int main(){
Init();
while(~scanf("%d%d%d", &n, &k, &p)){
Getdata();
Solve();
}
return 0;
}