PAT甲级 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 = 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 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(<=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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值