程设2021期末题D:括号生成

原题: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 }

 

posted @ 2021-07-19 21:11  永远是个小孩子  阅读(617)  评论(0编辑  收藏  举报