nyoj 19 擅長排列的小明 【全排列(n中抽取m個數)】
阿新 • • 發佈:2019-01-23
擅長排列的小明
時間限制:1000 ms | 記憶體限制:65535 KB 難度:4- 描述
- 小明十分聰明,而且十分擅長排列計算。比如給小明一個數字5,他能立刻給出1-5按字典序的全排列,如果你想為難他,在這5個數字中選出幾個數字讓他繼續全排列,那麼你就錯了,他同樣的很擅長。現在需要你寫一個程式來驗證擅長排列的小明到底對不對。
- 輸入
- 第一行輸入整數N(1<N<10)表示多少組測試資料,
每組測試資料第一行兩個整數 n m (1<n<9,0<m<=n) - 輸出
- 在1-n中選取m個字元進行全排列,按字典序全部輸出,每種排列佔一行,每組資料間不需分界。如樣例
- 樣例輸入
-
2 3 1 4 2
- 樣例輸出
-
1 2 3 12 13 14 21 23 24 31 32 34 41 42 43
- 來源
- 上傳者
思路:
以1-n開始為第一個數開始遍歷,然後進行遞迴賦值第二個數,輸出,直至到n結束迴圈!
程式碼:
//從1開始遞迴,然後看看是否滿足m個數,如果滿足兩個數,那麼就將這兩個數 //輸出,然後繼續進行賦值遞迴,直到所有的數輸出結束之後,然後vis[i]就也都是0了 //然後從第二個開始為起始數字,進行找第二個數(進行遞迴查詢),找到就輸出,一直這樣 //查詢,直到查詢結束為止! #include <stdio.h> #include <string.h> int n,m; int vis[10]; int a[10]; void dfs(int num) { if(num==m)//和對n個數進行全排列差別就是將這的n換成m,每次排列滿足m個數就輸出! { for(int i=0;i<m;i++) { printf("%d",a[i]); } printf("\n"); return; } for(int i=1;i<=n;i++) { if(!vis[i]) { vis[i]=1; a[num]=i; dfs(num+1);//每次輸出一次,就會取消一次標記,然後繼續進行迴圈,為陣列a賦值 vis[i]=0;//然後繼續進行遞迴,看是否滿足m==n,如果不滿足,繼續遞迴賦值,直到滿足條件,進行輸出為止 } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(vis,0,sizeof(vis)); dfs(0); } return 0; }