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
我的思路:
1. 用 n / k ,然后开根号p 得到最大的因子, 接着进行dfs, 从最大的因子开始,填因子序列,直到到k个为止,写出的代码有点问题(毕竟我是搜索渣渣),但是参考了柳神的代码,感觉思路可以, 重新写一写!
补:
24分,错了2个点
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int n, k, p;
vector<int> temp , ans;
int maxFacSum = -1; //记录全局最大因子和
double round(double r) // 四舍五入求最大因子
{
return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}
void dfs(int index,int maxFac,int nowSum,int sum) //index代表因子序列位置,maxFac目前最大的因子,nowSum表示目前的和,sum表当前因子和
{
if (index == k) //找到结果
{
if (nowSum == n && sum > maxFac)
{
maxFacSum = sum;
ans = temp;
}
return;
}
for (int i = maxFac; i > 0; i--) //从最大因子开始枚举
{
if (nowSum + pow(i*1.0, p) <= n) //如果 和<n 才可以填
{
temp[index] = i; //在index位置填上该因子
dfs(index+1, i, nowSum + pow(i*1.0, p), sum+i); //递归填index+1位置
}
if(index == k - 1) return;
}
}
int main()
{
scanf("%d %d %d", &n, &k, &p);
int maxFactor = (int)round(sqrt(round(n / (k*1.0))));
temp.resize(k);
dfs(0,maxFactor,0,0); //要填0号位置,最大因子是maxFactor,当前和为n,因子和为0
if (maxFacSum == -1)
{
printf("Impossible");
return 0;
}
printf("%d =", n);
for (int i = 0; i < ans.size(); i++)
{
if (i == ans.size() - 1)
{
printf(" %d^%d",ans[i], p);
return 0;
}
printf(" %d^%d +", ans[i], p);
}
}
参考代码:
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int n, k, p;
vector<int> v, temp, ans;
int maxFacSum = -1;
void init() //此举的目的是保存i的p次方,知道其 <= n
int temp = 0, index = 1;
while(temp <= n)
{
v.push_back(temp);
temp = pow(index*1.0, p); //这个地方不能写成pow(index,p),在vs2010里面编译的时候无法匹配列表,正确是double pow(double r,int p)
index++;
}
}
void dfs(int index,int tempSum,int nowK,int facSum) //index代表因子,tempSum是当前因为的p次幂的和,nowK是当前的因子个数,facSum是当前的因子和
{
if (nowK == k) //选了k个因子
{
if (tempSum == n && facSum > maxFacSum) //和正好是n 并且当前因子和 > 全局因子和,进行更新
{
ans = temp;
maxFacSum = facSum;
}
return;
}
while (index >= 1)
{
if (tempSum + v[index] <= n) //只有目前和+要选的因子的p次幂的和<n时,才进行选择
{
temp[nowK] = index;
dfs(index,tempSum+v[index], nowK+1, facSum+index);
}
if (index == 1) return;
index--;
}
}
int main()
{
scanf("%d %d %d", &n, &k, &p);
init();
temp.resize(k);
dfs(v.size()-1, 0, 0, 0); //从最大开始,才能降序输出
if (maxFacSum == -1) {
printf("Impossible");
return 0;
}
printf("%d = ", n);
for (int i = 0; i < ans.size(); i++) {
if (i != 0) printf(" + ");
printf("%d^%d", ans[i], p);
}
return 0;
}