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 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 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
主要思路
代码参考了柳神的代码使用深度优先搜索,首先将v[i]存储数字对应的次方便于后面直接调用。 而后在DFS代码的书写中首先确定跳出的条件,一个是满足题目所说表示的k,p条件,另一个就是当myk的值大于题目给的k时跳出(这个条件在本题中使用无效只是说在刚写代码时应注意判断)
DFS中的myn,myk用于存储当前获得的值的总数以及插入fac的个数,fac用于暂时存储当前路径,fac存储当前的数字总和便于直接获取和最大的路径。在每次进行路径插入的时候为了保证数字时按照从大到小的数字插入的应该对Index进行保存(便于保证下一次插入的数字不比当前的数字大),因而在DFS函数中存放index变量的值。
在实际代码书写过程中注意所有需要使用的变量尽量在函数的参数中防止递归过程中出错(笔者比较菜,递归经常出错)
为了提高运行效率,对于一定无法满足条件的数字进行剔除,也就是必须满足v[i]*(k-myk)>=n-myn条件
代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
int n, k, p, maxfac=0;
vector<int> v ,tans,ans;
void init()
{
int i = 1;
v.push_back(0);
while (pow(i, p) <= n)
{
v.push_back(pow(i, p));
i++;
}
}
void GetNum(int index,int myn, int myk, int fac)
{
if (myn >n || myk >k)
return;
if (myn == n && myk == k)
{
if (fac > maxfac)
{
maxfac = fac;
ans = tans;
}
return;
}
for (int i = index; i >0; i--)
{
if (myn < myk)
continue;
if (v[i] + myn <= n&&v[i]*(k-myk)>=n-myn)
{
tans.push_back(i);
GetNum(i, myn + v[i], myk + 1, fac + i);
tans.pop_back();
}
}
};
int main()
{
cin >> n >> k >> p;
int m;
m = pow((double)n, 1.0 / p);
init();
if (pow(m, p) == n)
m--;
GetNum(v.size() - 1, 0, 0, 0);
if (ans.size() == 0)
cout << "Impossible";
else
{
cout << n << " = ";
cout << ans[0] << "^"<<p;
for (int i = 1; i < ans.size(); i++)
{
cout << " + " << ans[i] << "^"<<p;
}
}
}