(难+)A1103 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 12​2​​+4​2​​+2​2​​+2​2​​+1​2​​, or 11​2​​+6​2​​+2​2​​+2​2​​+2​2​​, 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 { a​1​​,a​2​​,⋯,a​K​​ } is said to be larger than { b​1​​,b​2​​,⋯,b​K​​ } if there exists 1≤L≤K such that a​i​​=b​i​​ for i<L and a​L​​>b​L​​.

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,将 N 表示为 K 个正整数(可以相同,递减排列)的 P 次方的和,即 N=n1^P+n2^p+...+nk^P, 如果有多种方案,那么底数和 n1+n2+...+nk 最大的方案;如果还有多种,那么选择底数序列的字典序的最大方案。

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n, k, p, maxFacSum = -1;    //maxFacSum记录最大底数之和
vector<int> fac, ans, temp;     //fac 记录 0^p, 1^p, 2^p, 记录到不超过 n 的数,ans 存放最优底数序列,temp 存放递归过程中的临时底数序列
//power 函数计算 x^p
int power(int x){
    int ans = 1;
    for(int i = 0; i < p; i++){
        ans *= x;
    }
    return ans;
}
//init 函数预处理fac数组,注意把0也存进去
void init(){
    int i = 0, temp = 0;
    while(temp <= n){
        fac.push_back(temp);
        temp = power(++i);
    }
}
//DFS函数,当前访问fac[index],nowK为当前选中个数,sum为当前选中的数之和,facSum为当前选中的底数之和
void DFS(int index, int nowK, int sum, int facSum){
    if(sum == n && nowK == k){      //找到一个满足的序列
        if(facSum > maxFacSum){     //底数之和更优
            ans = temp;             //更新最优底数序列
            maxFacSum = facSum;     //更新最大底数之和
        }
        return;
    }
    if(sum > n || nowK > k)         //这种情况不会产生答案,直接返回
        return;
    if(index >= 1){                 //fac[0]不需要选择
        temp.push_back(index);      //把index加入临时序列temp
        DFS(index, nowK + 1, sum + fac[index], facSum + index);     //选的分支
        temp.pop_back();       //选的分支结束,把刚加进去的index出来
        DFS(index - 1, nowK, sum, facSum);  //不选的分支
    }
}
int main(){
    scanf("%d%d%d", &n, &k, &p);
    init();
    DFS(fac.size() - 1, 0, 0, 0);   //从fac的最后一位开始往前搜索
    if(maxFacSum == -1)
        printf("Impossible\n");
    else{
        printf("%d = %d^%d", n, ans[0], p);
        for(int i = 1; i < ans.size(); i++){
            printf(" + %d^%d", ans[i], p);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_35093872/article/details/87889288