从 1∼n这 n 个整数中随机选出 m 个,输出所有可能的选择方案。
输入格式 两个整数 n, m 在同一行用空格隔开。
输出格式 按照从小到大的顺序输出所有方案,每行 1 个。
首先,同一行内的数升序排列,相邻两个数用一个空格隔开。
其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如 1 3 5 7
排在 1 3 6 8
前面)。
数据范围 n>0 , 0≤m≤n , n+(n−m)≤25
输入样例:
输出样例: 1 2 3 4 5 6 7 8 9 10 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;int n, m;void dfs (int u, int sum, int state) { if (sum + n - u < m) return ; if (sum == m) { for (int i = 0 ; i < n; i++) if (state >> i & 1 ) cout << i + 1 << ' ' ; cout << '\n' ; return ; } dfs (u + 1 , sum + 1 , state | 1 << u); dfs (u + 1 , sum, state); } int main () { cin >> n >> m; dfs (0 , 0 , 0 ); return 0 ; }
思考题 :如果要求使用非递归方法,该怎么做呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream> #include <stack> using namespace std;struct State { int pos, u, sum, state; }; int main () { int n, m; cin >> n >> m; stack<State> stk; stk.push ({0 , 0 , 0 , 0 }); while (stk.size ()) { auto t = stk.top (); stk.pop (); if (t.pos == 0 ) { if (t.sum + n - t.u < m) continue ; if (t.sum == m) { for (int i = 0 ; i < n; i++) if (t.state >> i & 1 ) cout << i + 1 << ' ' ; cout << '\n' ; continue ; } t.pos = 1 ; stk.push (t); stk.push ({0 , t.u + 1 , t.sum + 1 , t.state | 1 << t.u}); } else if (t.pos == 1 ) { t.pos = 2 ; stk.push (t); stk.push ({0 , t.u + 1 , t.sum, t.state}); } else continue ; } }