PAT-A 真题- 1103. Integer Factorization

发布于 / PAT-甲级 / 0 条评论

原题干:

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 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

生词:

factorization : 因数分解                        positive : 正的,阳性的

solution : 答案                                      non-increasing : 非增的

unique : 唯一的,仅有的                      factor : 因子

sequence : 序列


题目大意:

给出一个数N,找到K个数,使这K个数的P次幂相加,结果等于N

如果有多种答案,则找出这k个数之和,最大的一种答案。

如果仍然有多种答案,则找出字典序最大的一种答案


这道题可以使用DFS算法解决,具体讲解在注释里讲的很清晰了,这里不做过多解释

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

/*  *
    * 全局变量,n为题目要求的和,k为几项,p为幂
    * result为最终结果,tmp为每次的结果,table存放幂运算结果
    */
int n, k, p;
int max_result = -1;
vector<int> result, tmp, table;


/*  *
    * 打表,table下标的p次幂
*/
void create_table(){
    int it = 1;
    for(int i = 0; i <=n; i = pow(it++, p))
        table.push_back(i);
}

/*  *
    * DFS深度优先搜索函数
    * index为当前处理的数,CURRENT_N为当前幂运算后的和,CURRENT_K为当前已经处理过多少数,K_ALL_SUM为当前处理过的数的和
    * "死胡同"为CURRENT_N或者CURRENT_K==k的时候。"岔道口"为继续算自己,或者处理下一个数。
    * 169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
*/

void DFS(int index, int CURRENT_N, int CURRENT_K, int K_ALL_SUM){
    //死胡同
    if(CURRENT_N >= n || CURRENT_K == k){
        if(CURRENT_N == n && K_ALL_SUM > max_result && CURRENT_K == k){
            max_result = K_ALL_SUM;
            result = tmp;
        }
        return;
    }
    //岔路口,index=0的时候就不能继续进行了
    if(index){
        //第一条路,计算自己
        tmp.push_back(index);
        DFS(index, CURRENT_N + table[index], CURRENT_K + 1, K_ALL_SUM + index);
        //第二条路,不计算自己,计算下一个数
        tmp.pop_back();
        DFS(index - 1, CURRENT_N, CURRENT_K, K_ALL_SUM);
    }
}

int main(){
    cin >> n >> k >> p;
    create_table();
    DFS(table.size() - 1, 0, 0, 0);
    if(max_result == -1) {
        printf("Impossible");
        return 0;
    }
    printf("%d = ", n);
    for(int i = 0; i < result.size(); i++) {
        if(i != 0) printf(" + ");
        printf("%d^%d", result[i], p);
    }
    return 0;
}

转载原创文章请注明,转载自: 斐斐のBlog » PAT-A 真题- 1103. Integer Factorization
目前还没有评论,快来抢沙发吧~