SGU 179 Brackets light(生成字典序的下一个序列)

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=179

解题报告:输入一个合法的括号串,求出这个括号串的字典序的下一个串。(认为'(' < ')')

我的做法主要是用了生成字典序的下一个序列的思想:

1.从序列的尾部开始往前找,找到第一个升序的位置例如 2 5 4 3 对于这个序列来说就是2 5这个位置

2.然后在后面这个降序的序列中找到一个比这个2稍大一点的数跟2进行交换得到3 5 4 2

3.然后把这个位置的后面的串转过来得到3 2 4 5,这就是我们要的结果

对于这题来说,串中只有()这两种字符,所以我们在找第一个升序的位置的时候只要找到形如‘(’ ‘)’这样的序列的位置就是了

然后还有一个存不存在下一个字典序列的问题。我们看,对于形如(())这样有嵌套关系的括号,我们总是可以通过把这层嵌套拆开来得到一个更大的序列,

所以我们想到形如()()这样的序列不能拆开,所以,我们只要判断是不是()()这样的序列就可以了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<deque>
 8 using namespace std;
 9 const int maxn = 10000+5;
10 char str[maxn];
11 
12 int update(char *s)
13 {
14     int i,len = strlen(s);
15     for(i = len - 1;i > 0;--i)
16     if(s[i] > s[i-1])
17     {
18         swap(s[i],s[i-1]);
19         reverse(s+i+1,s+len);
20         return 1;
21     }
22     return 0;
23 }
24 int judge(char *s)
25 {
26     int len = strlen(s);
27     deque<char> que;
28     for(int i = 0;i < len;++i)
29     {
30         if(s[i] == '(')
31         que.push_front(s[i]);
32         else
33         {
34             if(que.empty())
35             return 0;
36             else que.pop_front();
37         }
38     }
39     que.clear();
40     return que.empty();
41 }
42     
43 int main()
44 {
45     while(scanf("%s",str)!=EOF)
46     {
47         int l,len = strlen(str),flag = 1;
48         for(l = 0;l < len;++l)
49         if(str[l] == '(' && str[l+1] != ')')
50         break;
51         if(l >= len)
52         flag = 0;
53         while(flag)
54         {
55             update(str);
56             if(judge(str))
57             break;
58         }
59         printf(flag? "%s\n":"No solution\n",str);
60     }
61     return 0;
62 }
View Code
posted @ 2014-07-18 21:24  xiaxiaosheng  阅读(407)  评论(0编辑  收藏  举报