时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个只包含括号和小写字母的字符串S,例如S="a(bc(de)fg)hijk"。
其中括号表示将里面的字符串翻转。(注意括号可能嵌套)
请你输出翻转之后的字符串。
输入
字符串S。
对于50%的数据,|S| ≤ 1000
对于100%的数据, |S| ≤ 5000000
输出
输出反转后的字符串(不带括号)。
- 样例输入
-
a(bc(de)fg)hijk
- 样例输出
agfdecbhijk
大意:给出一个字符串,里面有合法的小括号,小括号内的字符串反转,输出最后的序列(去掉括号)
解析:正如我们看到括号配对的联想,这题就是一个栈或者说递归,考场上不知道为何50分暴力也写错了~~~
正解:首先将括号配对(用两个数组分别记录左括号对应右括号的的位置 和 右括号对应左括号的位置)
然后就开始正序遍历,遇到普通非括号字符直接输出,遇到左括号,假装反转括号内的字符(添加rev标记并进入下次递归)
如果有rev标记,逆序遍历,遇到普通非括号字符直接输出,遇到右括号,假装反转括号内的字符(去除rev标记并进入下次递归)
就这么愉快的结束了,不过评测姬如果是windows的话怕是会爆栈,可以考虑加个手工栈。
1 /* 2 Welcome Hacking 3 Wish You High Rating 4 */ 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<ctime> 9 #include<cstdlib> 10 #include<algorithm> 11 #include<cmath> 12 #include<string> 13 using namespace std; 14 int read(){ 15 int xx=0,ff=1;char ch=getchar(); 16 while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();} 17 while(ch>='0'&&ch<='9'){xx=(xx<<3)+(xx<<1)+ch-'0';ch=getchar();} 18 return xx*ff; 19 } 20 const int maxn=5000010; 21 int N,stack[maxn],tp,Prev[maxn],Next[maxn]; 22 char s[maxn]; 23 void dfs(int st,int en,bool rev){ 24 if(!rev){ 25 for(int i=st;i<=en;i++){ 26 if(s[i]!='(') 27 printf("%c",s[i]); 28 else{ 29 dfs(i+1,Next[i]-1,1); 30 i=Next[i]; 31 } 32 } 33 } 34 else{ 35 for(int i=en;i>=st;i--){ 36 if(s[i]!=')') 37 printf("%c",s[i]); 38 else{ 39 dfs(Prev[i]+1,i-1,0); 40 i=Prev[i]; 41 } 42 } 43 } 44 } 45 int main(){ 46 //freopen("in","r",stdin); 47 //freopen("out","w",stdout); 48 gets(s); 49 N=strlen(s); 50 for(int i=0;i<N;i++){ 51 if(s[i]=='(') 52 stack[++tp]=i; 53 else if(s[i]==')'){ 54 Next[stack[tp]]=i; 55 Prev[i]=stack[tp]; 56 tp--; 57 } 58 } 59 dfs(0,N-1,0); 60 return 0; 61 }
仍然是高仿某位大神的代码,超好背的呢!看了一遍,就默写出来AC了呢!