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