• PAT 1103 Integer Factorization[难]


    1103 Integer Factorization(30 分)

    The KP 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 KP 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<P7). 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 1LK 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,以及数量K,指数P,将N用K个数的N次方的和进行表示。如果相同输出因子数最小的,如果还相同,那么输出较大(字典序较大的)的那个。

     //感觉好难,是不是dfs什么的?果然大佬觉得有趣的题目都这么难。

     考点是DFS+剪枝。

      代码来自:https://www.liuchuo.net/archives/2451

    #include <iostream>
    #include <vector>
    #include <cmath>
    using namespace std;
    int n, k, p, maxFacSum = -1;
    vector<int> v, ans, tempAns;
    void init() {
        int temp = 0, index = 1;
        while (temp <= n) {
            v.push_back(temp);
            temp = pow(index, p);
            index++;
        }
    }
    //index表示当前可用的数最大的下标。
    //底数和tempSum
    //个数要求tempK
    //facSum底数积
    void dfs(int index, int tempSum, int tempK, int facSum) {
        if (tempK == k) {
            if (tempSum == n && facSum > maxFacSum) {
                    ans = tempAns;//新解赋值
                    maxFacSum = facSum;
            }
            return;
        }
        while(index >= 1) {//这个index从大到小的过程,就保证了是按字典序从大到小排列的。
            if (tempSum + v[index] <= n) {
                tempAns[tempK] = index;
                dfs(index, tempSum + v[index], tempK + 1, facSum + index);
            }
            if (index == 1) return;
            index--;
        }
    }
    int main() {
        scanf("%d%d%d", &n, &k, &p);
        init();
        tempAns.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;
    }

    //真的是学习了!

    1.注意剪纸,dfs里需要有这一句:if (tempSum + v[index] <= n) 这样比进入下一层要开销小很多。

    下面这个代码来自:https://www.cnblogs.com/chenxiwenruo/p/6119360.html

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <cmath>
    using namespace std;
    /**
    其实可以预先把i^p<n的i都存储起来
    **/
    const int maxn=405;
    int res[maxn];
    int ans[maxn];
    int factor[maxn];
    int fidx=0;
    int maxsum=0;
    bool flag=false;
    int n,k,p;
    /**
    num为当前的总和
    cnt为还剩几个i^p项,即当前的k
    sum为各因子的总和,因为要取和最大的
    last为上一个因子的索引,因为要保证因子从大到小输出,
        所以dfs后一个因子在factor中的索引不能大于上一个
    **/
    void dfs(int num,int cnt,int sum,int last){
        if(num==0&&cnt==0){
            if(sum>maxsum){
                flag=true;
                for(int i=1;i<=k;i++)
                    ans[i]=res[i];
                maxsum=sum;
            }
            return;
        }
        else if(cnt==0)
            return;//计数用完了,但是不符合=n的要求
        for(int i=last;i>=0;i--){
            int left=num-factor[i];
                res[cnt]=i+1;
                dfs(left,cnt-1,sum+i,i);
        }
    }
    
    int main()
    {
        scanf("%d %d %d",&n,&k,&p);
        int tmp=0;
        fidx=0;
        //预先存储i^p<=n的i
        while(tmp<=n){
            factor[fidx]=tmp;
            fidx++;
            tmp=pow(fidx+1,p);
        }
        int cnt=0;
        int last=fidx-1;
    
        dfs(n,k,0,last);
        if(flag){
            printf("%d =",n);
            for(int i=k;i>=2;i--){
                printf(" %d^%d +",ans[i],p);
            }
            printf(" %d^%d",ans[1],p);
        }
        else{
            printf("Impossible");
        }
    
        return 0;
    }

    //但是这个目前有点问题,今晚修改一下,看问题出在哪,顺便也是学习了!

  • 相关阅读:
    偏态分布的均值与中位数关系
    Leetcode 769. Max Chunks To Make Sorted
    【STL】max_element()函数
    [LeetCode] 1338. Reduce Array Size to The Half
    [LeetCode] 985. Sum of Even Numbers After Queries
    [LeetCode] 984. String Without AAA or BBB
    [LeetCode] 1405. Longest Happy String
    [LeetCode] 1646. Get Maximum in Generated Array
    [LeetCode] 926. Flip String to Monotone Increasing
    [LeetCode] 1658. Minimum Operations to Reduce X to Zero
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9508896.html
Copyright © 2020-2023  润新知