遞迴(dfs)實現指數,組合,排列型列舉
阿新 • • 發佈:2022-03-28
指數型
題目:
從 1∼n 這 n 個整數中隨機選取任意多個,輸出所有可能的選擇方案。
輸入格式
輸入一個整數 n。
輸出格式
每行輸出一種方案。
同一行內的數必須升序排列,相鄰兩個數用恰好 1 個空格隔開。
對於沒有選任何數的方案,輸出空行。
本題有自定義校驗器(SPJ),各行(不同方案)之間的順序任意。
資料範圍
1≤n≤15
輸入樣例:
3
輸出樣例:
3
2
2 3
1
1 3
1 2
1 2 3
程式碼:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 16; int st[N]; int n; void dfs(int u) { if(u>n) { for (int i = 1; i <= n; i ++ ) if(st[i]==1) printf("%d ",i); printf("\n"); return; } st[u]=2; dfs(u+1); st[u]=0; st[u]=1; dfs(u+1); st[u]=0; } int main() { scanf("%d", &n); dfs(1); return 0; }
組合型
題目
從 1∼n 這 n 個整數中隨機選出 m 個,輸出所有可能的選擇方案。
輸入格式
兩個整數 n,m ,在同一行用空格隔開。
輸出格式
按照從小到大的順序輸出所有方案,每行 1 個。
首先,同一行內的數升序排列,相鄰兩個數用一個空格隔開。
其次,對於兩個不同的行,對應下標的數一一比較,字典序較小的排在前面(例如 1 3 5 7 排在 1 3 6 8 前面)。
資料範圍
n>0 ,
0≤m≤n ,
n+(n−m)≤25
輸入樣例:
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
程式碼:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 30; int n,m; int way[N]; void dfs(int u,int start) { if(u+n-start<m) return; if(u==m+1) { for (int i = 1; i <= m; i ++ ) printf("%d ",way[i]); puts(""); return; } for (int i = start; i <= n; i ++ ) { way[u]=i; dfs(u+1,i+1); way[u]=0; } } int main() { cin >>n>>m; dfs(1,1); return 0; }
排列型
題目
把 1∼n 這 n 個整數排成一行後隨機打亂順序,輸出所有可能的次序。
輸入格式
一個整數 n。
輸出格式
按照從小到大的順序輸出所有方案,每行 1 個。
首先,同一行相鄰兩個數用一個空格隔開。
其次,對於兩個不同的行,對應下標的數一一比較,字典序較小的排在前面。
資料範圍
1≤n≤9
輸入樣例:
3
輸出樣例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
題目入口
程式碼:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10;
int st[N];
bool used[N];
int n;
void dfs(int u)
{
if(u>n)
{
for (int i = 1; i <= n; i ++ ) printf("%d ",st[i]);
puts("");
return;
}
for (int i = 1; i <= n; i ++ )
{
if(!used[i])
{
st[u]=i;
used[i]=true;
dfs(u+1);
st[u]=0;
used[i]=false;
}
}
}
int main()
{
cin >> n;
dfs(1);
return 0;
}