Informatics Orsay Yitong 1317:[例5.2]出力検索dfとバックトラッキングの組み合わせ(粑粑)

1317:[例5.2]結合された出力

時間制限:1000ミリ秒メモリ制限:65536 KB
コミットメント:13575パス:6581
[タイトルの説明]
配置と組み合わせは、n要素からr要素を抽出するために一般的に使用される数学的方法です(順序なし、r≤ n)、n要素を自然数1、2、...、nとして単純に理解し、それらから任意のr数を取得できます。

ここで、すべての組み合わせを再帰的に出力する必要があります。

たとえば、n = 5、r = 3、すべての組み合わせは次のとおりです。

1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5

[入力]
2つの自然数nおよびrの1行(1 <n <21、1≤r≤n)。

[出力]
すべての組み合わせについて、各組み合わせは行を占め、その中の要素は昇順で配置され、各要素は3文字を占め、すべての組み合わせも辞書順になっています。

[入力例]
5 3
[出力例]
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5


配列bを使用して、その位置の数値が使用されたかどうかを判別し、[k]を使用して判別された数値を格納します。
たとえば、出力1 2 4
a [1] = 1、a [2] = 2、a [3] = 4
b [1] = 1、b [2] = 1、b [4] = 1

ババは最初はここでdfを使用する方法を理解していませんでしたが、子供はババに理解方法を伝えました。

キーは、コードdfsの最初のループです。本の例に従っている場合(245ページ、元の本はint i = 1、現在はint i = a [k-1] +1;の場合)、print小さいものから大きいものだけでなく、このように大きいものから小さいものまで5 4 3も含まれています。

子供のように。


#include<bits/stdc++.h>
#define N 22
using namespace std; 
int num=0,a[10001]={0},n,r;
bool b[10001]={0};
int dfs(int);
int print();
int main(){
	freopen("cpp.in","r",stdin);
	freopen("cpp.out","w",stdout);
    cin>>n>>r; 
    dfs(1);
    return 0;
}
int dfs(int k){
	int i;
	for(i=a[k-1]+1;i<=n;i++){
		if(!b[i]){
			a[k]=i;
			b[i]=1;
			if(k==r){
				print();
			}
			else {
				dfs(k+1);
			}
			b[i]=0;
		}
	}
}
int print(){
	num++;
	for(int i=1;i<=r;i++){
		cout<<setw(3)<<a[i];
	}
	cout<<endl;
}
公開された33元の記事 ウォンの賞賛0 ビュー167

おすすめ

転載: blog.csdn.net/weixin_42790071/article/details/105530215