1103. Integer Factorization (30)

1103. Integer Factorization (30)

時間限制
1200 ms
內存限制
65536 kB
代碼長度限制
16000 B
判題程序
Standard
作者
CHEN, Yue

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


#include <iostream>
#include <vector>
#include<cmath>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
vector<int> answer;
vector<int> test;
int number,M,K,i,N;
int a[410];
int sum=0; 
int sum_for_answer=0;
int geta_array(){
	int i=0;
	while(pow(i,K)<number){
		a[i++]=pow(i,K);
	}
	return i;
}
void getanswer(int n,int end,int begin){//遞歸實現遍歷,注意要去掉一些情況否則肯定會超時 
	int i,j,e=end;
	for(i=begin;i<end;i++){
		n-=a[i];
		if(n<M-test.size()-1||n<0){//這裏的n<0是如果出現n<0的情況,下面的代碼會出現錯誤,反映到結果裏就是超時 
			break;
		}
		test.push_back(1+i);
		sum+=1+i;
		if(n==0&&test.size()==M){
			if(sum>sum_for_answer){
				sum_for_answer=sum;
				answer=test;
			}
			else if(sum==sum_for_answer){
				for(j=0;j<answer.size();j++){
					if(test[j]<answer[j]){
					j=answer.size();
					break;
				}
					if(test[j]>answer[j])
					break;
				}
				if(j!=answer.size()){
					answer=test;
				}
			}
		}
		else {
		getanswer(n,e,i);//這裏取下界爲i是關鍵,不加這個的話遞歸肯定會超時 
		}
		n+=a[i];
		test.pop_back();
		sum-=i+1;
	}
}
int main(){
	cin>>number>>M>>K;
	N=geta_array();
	getanswer(number,N,0);
	if(answer.empty()){
		printf("Impossible\n");
		return 0;
	}
	printf("%d = ",number);
	for(i=answer.size()-1;i>=0;i--){
		printf("%d^%d",answer[i],K);
		if(i!=0)
		printf(" + ");
	}
} 
感想:
1.用遞歸實現遍歷
2.注意代碼裏提到的兩個點,就可以不超時
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章