PAT高度1103整数の因数分解(30)深さ優先探索DFS]

タイトル

Nの整数正のKP分解は、Kは正の整数のP乗の和としてNを書き込むことです。あなたは、任意の正の整数N、KおよびP.のためにNのKP分解を見つけるためにプログラムを書くことになっている
:入力仕様
、各入力ファイルには、行に3つの正の整数N(<= 400)を与える一つのテストケースが含まれていますK(<= N)とP(1 <P <= 7)。行中の数字は、スペースで区切られます。
出力仕様:
それぞれの場合について、溶液が存在する場合、形式に出力:
N = N [1] ^ P + ... N [K] ^ P
ここでのNi(iは、... K = 1)i番目の要素です。すべての要因は非増加順に印刷されなければなりません。注:ソリューションは、一意ではないかもしれません。例えば、169の5-2分解は9つのソリューションを有するような12 ^ 2 + 4 ^ 2 + 2 ^ 2 + 2 ^ 2 + 1 ^ 2、又は11 ^ 2 + 6 ^ 2 + 2 ^ 2 + 2として^ 2 + 2 ^ 2、またはそれ以上。あなたは、要因の最大合計で出力1をする必要があります。タイがある場合、最大の因子配列を選択しなければならない - シーケンス{A1、A2、... AK}は{B1、B2、... BK} 1 <= L <= Kが存在する場合、このようなAIよりも大きくなるように言われています私のために=双方向 bLをする場合は、解決策、シンプルな出力「インポッシブル」はありません。
サンプル入力1:
169 5 2
サンプル出力1:
169 = 6 ^ 2 + 6 ^ 2 + 6 ^ 2 + 6 ^ 2 + 5 ^ 2
サンプル入力2:
169 167 3
の出力例2:
不可

トピック分析

知られているもの、N、KおよびP = Nのに必要な電力の数
、および最大基部数列を取る場合の配列の複数、より大きな配列(二つの配列、iが等しい最初の項目であるいずれかの配列の複数が、依然として存在する場合、私は、+ 1項目以上)の
出力要件:シーケンス番号の昇順に非

問題解決のためのアイデア

  1. P定数は、コンテナに格納されているすべてのパワーp <= nの数(nより数Pが大きいのパワー場合、この数は選択することができない)の結果を前処理することができるので
  2. 現在の数が選択されて記録され、現在の番号は次の桁をスキップするオプションが選択されていない。現在のデジタル二つのブランチにデジタルトラバーサルの多数の小から検索のDFSの深さは、選択された数字は、再び、選択繰り返すことができるされています
  3. DFSの終了条件:
    3.1(有効な配列)選択された数の合計よりも大きいnは
    3.2(有効な配列)の桁数がKよりも大きく選択されている
    3.3(有効なシーケンスが)数字の和に等しく選択されているNと選択されています桁数が最適解を更新し、Kに等しいです

コード

#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;
}



おすすめ

転載: www.cnblogs.com/houzm/p/12555952.html