题目链接: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 ":"No solution ",str); 60 } 61 return 0; 62 }