原題:http://cxsjsx.openjudge.cn/2021finalpractise/D/
描述
Paul是一名數學專業的同學,在課余選修了C++編程課,現在他能夠自己寫程序判斷判斷一個給定的由'('和')'組成的字符串是否是正確匹配的。可是他不滿足於此,想反其道而行之,設計一個程序,能夠生成所有合法的括號組合,請你幫助他解決這個問題。
輸入
輸入只有一行N,代表生成括號的對數(1 ≤ N ≤ 10)。
輸出
輸出所有可能的並且有效的括號組合,按照字典序進行排列,每個組合占一行。
樣例輸入
3
樣例輸出
((()))
(()())
(())()
()(())
()()()
解法
這道題比較簡單,枚舉然后驗證就可以。
左括號對應0,右括號對應1,有效的括號組合就可以用01串來表示。看作2N位的01串。
從1到(2*N-1)枚舉,有效的括號組合滿足兩個條件:
- 有相同個數的0和1,都是N個
- 以0開頭,以1結尾,任何一個1前面有對應的0。也就是說,在任何一個位置所得的前綴中0的個數不少於1的個數。
代碼如下:
1 #include <iostream> 2 #include <bitset> 3 using namespace std; 4 int N; 5 bool judge(bitset<20>temp) { 6 int j = 0, num1 = 0; 7 while (j < 2*N) { 8 if (temp[j]) { 9 j++; num1++; 10 } 11 else { 12 j++; num1--; 13 } 14 if (num1 < 0) { 15 return false; 16 } 17 } 18 return true; 19 } 20 int main() { 21 cin >> N; 22 int max = 1 << (2*N - 1);//這里是2*N-1而不是2*N是因為1在最左邊一定不成立,所以第一位一定是0,減少搜索量 23 for (int i = 1; i < max; i++) { //這里可以是i+=2,因為最后一位必須是1,不能是0,所以可以只考慮奇數 24 bitset<20> temp; 25 int cnt0 = 0, cnt1 = 0; 26 for (int j = 0; j < 2 * N; j++) { 27 temp[j] = (i >> j) & 1; 28 if (temp[j]) 29 cnt1++; 30 else 31 cnt0++; 32 } 33 if (cnt1 != cnt0) 34 continue; 35 if (judge(temp)) { 36 for (int j = 0; j < 2 * N; j++) { 37 if (temp[2 * N - 1 - j]) 38 cout << ")"; 39 else cout << "("; 40 } 41 cout << endl; 42 } 43 } 44 return 0; 45 }