構造增量法生成子集
阿新 • • 發佈:2017-07-11
amp 顯式 字典序 == sin 分析 cnblogs false !=
題意:
生成 1~n 集合的子集, 先按元素從小到大再按字典序排列輸出
分析:
所謂構造增量法, 就是每次都輸出當前數組的元素, 然後再給當前數組最大元素一個增量, 看是否仍然在集合內, 如果在就把他繼續放進數組, 輸出。 這種方法不需要顯式確認遞歸邊界, 如果無法添加元素, 自然就不會再遞歸了。 數據結構我選用了string , 因為字典序比較容易排序出來。
#include <bits/stdc++.h> using namespace std; string ans[1 << 15 + 5]; int A[10]; int cnt = 0; void print_subset(intn, int* A, int cur){ for(int i = 0; i < cur; i++) { ans[cnt] += A[i] + ‘0‘; } cnt++; int s = cur ? A[cur-1] + 1 : 1;// 確定已選元素的最大可能值 for(int i = s; i <= n; i++){ A[cur] = i; print_subset(n, A, cur + 1); // 遞歸構造子集 } } bool cmp(string a, string b){if(a.size() < b.size()) return true; else if(a.size() == b.size()){ return a < b; } else return false; } int main() { int n; while(scanf("%d", &n) != EOF){ cnt = 0; print_subset(n, A, 0); sort(ans, ans + cnt, cmp); cout << 0 <<endl;for(int i = 1; i < cnt; i++){ cout << ans[i].size() <<" " << ans[i][0] - ‘0‘; for(int j = 1; j < ans[i].size(); j++){ cout <<" " << ans[i][j] - ‘0‘; } ans[i] = ""; cout << "\n"; } printf("\n"); } return 0; }
構造增量法生成子集