• PAT Advanced 1103 Integer Factorization (30) [深度优先搜索DFS]


    题目

    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 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 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 { a1, a2, … aK} is said to be larger than { b1, b2, … bK } if there exists 1<=L<=K such that ai=bi for ibL 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
    若有多个序列,取底数和最大的序列;若仍有多个序列,取大序列(两个序列,前i项都相等,第i+1项较大者)
    输出要求:序列中数字非升序排列

    解题思路

    1. 因为p不变,可以预处理将所有p次方结果<=n的数字保存于容器(若某个数的p次方大于n,那么这个数字不可能被选中)
    2. dfs深度搜索,从大数字到小数字遍历,被选中数字可以重复再次被选中,所以当前数字有两种支路:当前数字被选择并记录;当前数字不被选择跳过选择下个数字
    3. dfs退出条件:
      3.1 (无效序列)已被选中的数字之和大于n
      3.2 (无效序列)已被选中的数字个数大于k
      3.3 (有效序列)已被选中的数字之和等于n并且已被选中的数字个数等于k,更新最优解

    Code

    #include <iostream>
    #include <vector>
    using namespace std;
    int n,k,p,maxSum;
    vector<int> fac,ans,temp;
    int power(int x) {
    	// 方法一:p个x相乘
    	int ans =1;
    	for(int i=0; i<p; i++)
    		ans*=x;
    	return ans;
    	//方法二:使用cmath中power函数
    }
    void init() {
    	for(int i=0; power(i)<=n; i++)
    		fac.push_back(power(i));
    }
    // index 当前访问的索引
    // numK 当前已经选择的数字个数
    // sum 当前已经选择的数字之和
    // facnum 当前已经选中的数字底数之和
    void dfs(int index, int numK,int sum,int facSum) {
    	if(sum==n&&numK==k) {
    		// 符合条件,更新最优解
    		if(facSum>maxSum) {
    			ans=temp; //保存序列
    			maxSum=facSum; //更新底数和最大值
    		}
    		return;
    	}
    	if(sum>n||numK>k)return;
    	if(index>=1) { //不选0
    		temp.push_back(index);
    		dfs(index, numK+1, sum+fac[index], facSum+index); //选择当前数字
    		temp.pop_back();
    		dfs(index-1, numK, sum, facSum); //不选择当前数字
    	}
    }
    int main(int argc,char *argv[]) {
    	scanf("%d %d %d",&n,&k,&p);
    	init(); //预处理数字的固定幂次结果 
    	dfs(fac.size()-1,0,0,0);
    	if(ans.empty()) printf("Impossible");
    	else {
    		printf("%d = %d^%d",n, ans[0], p);
    		for(int i=1; i<k; i++)
    			printf(" + %d^%d", ans[i], p);
    	}
    	return 0;
    }
    

    Code 2

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=410;
    int n,k,p,pw[maxn],maxi,maxfacsum=-1;
    vector<int> ans,temp;
    void initial(int v) {
    	for(int i=0; pow(i,p)<=v; i++) {
    		pw[i]=pow(i,p);
    		maxi = i;
    	}
    }
    void dfs(int index,int tempsum,int tempk,int facsum) {
    	if(tempk==k) {
    		if(tempsum==n&&facsum>maxfacsum) {
    			maxfacsum=facsum;
    			ans=temp;
    		}
    		return;
    	}
    //	while(index>=1){
    //		if(tempsum+pw[index]<=n){
    //			temp[tempk]=index;
    //			dfs(index,tempsum+pw[index],tempk+1,facsum+index);
    //		}
    ////		if(index==1)return;
    //		index--;
    //	}
    	for(int i=index; i>=1; i--) {
    		if(tempsum+pw[i]<=n) {
    			temp[tempk]=i;
    			dfs(i,tempsum+pw[i],tempk+1,facsum+i);
    		}
    	}
    
    }
    int main(int argc,char * argv[]) {
    	scanf("%d%d%d",&n,&k,&p);
    	initial(n);
    	temp.resize(k);
    	dfs(maxi,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;
    }
    



  • 相关阅读:
    2021软件工程-第一周作业01准备工作
    String.matches()的用法
    Idea使用JSP出现404问题---已解决
    如何解决Tomcat启动闪退现象(环境配置没问题)
    解决启动java的web项目时端口占用问题
    IntelliJ IDEA 连接数据库 详细过程-包含使用jdbc连接数据库
    ApplicationContextAware接口认识
    RestTemplate 服务间接口调用
    maven相关
    FastJson:json字符串与Java对象转换
  • 原文地址:https://www.cnblogs.com/houzm/p/12555952.html
Copyright © 2020-2023  润新知