PAT A1103 Integer Factorization (30 分)(深度优先搜索)

mac2022-06-30  39

1103 Integer Factorization (30 分)

The K−PK-PK−P factorization of a positive integer NNN is to write NNN as the sum of the PPP-th power of KKK positive integers. You are supposed to write a program to find the K−PK-PK−P factorization of NNN for any positive integers NNN, KKK and PPP.

Input Specification:

Each input file contains one test case which gives in a line the three positive integers NNN (≤400\le 400≤400), KKK (≤N\le N≤N) and PPP (1<P≤71 < P\le 71<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 122+42+22+22+1212^2 + 4^2 + 2^2 + 2^2 + 1^212​2​​+4​2​​+2​2​​+2​2​​+1​2​​, or 112+62+22+22+2211^2 + 6^2 + 2^2 + 2^2 + 2^211​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,⋯,aKa_1, a_2, \cdots , a_Ka​1​​,a​2​​,⋯,a​K​​ } is said to be larger than { b1,b2,⋯,bKb_1, b_2, \cdots , b_Kb​1​​,b​2​​,⋯,b​K​​ } if there exists 1≤L≤K1\le L\le K1≤L≤K such that ai=bia_i=b_ia​i​​=b​i​​ for i<Li<Li<L and aL>bLa_L>b_La​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次方的和。若有多种方案,则选择底数和最大的方案,若还有多种方案,则选择字典序最大的方案。

参考代码:

#include <cstdio> #include <vector> #include <algorithm> using namespace std; int n,p,k,maxFacsum=-1; //fac 记录0^p,1^p,...i^p,使得i^p为不超过n的最大整数 //ans存放最优底数序列,temp存放递归中的临时底数序列 vector <int> fac,ans,temp; int power(int x) //计算x^p { int ans=1; for(int i=0;i<p;++i) ans*=x; return ans; } void init() //init函数预处理fac数组,注意把0也存进去 { int i=0,temp=0; while(temp<=n) //当i^p没有超过n时,不断把i^p加入fac { 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>=0) //fac[0]不需要选择 { temp.push_back(index); //把底数index加入临时序列temp; DFS(index,nowk+1,sum+fac[index],facsum+index); //选的分支 temp.pop_back(); //选的分支结束后把刚才加进去的数pop掉 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; }

 

最新回复(0)