HihoCoder 1671 DFS
本以为是个简单的水题,好吧,其实就是个水题,虽然我还是……
题意的理解上有一点小小的问题orz,这里的括号里的字母是可以看成一个整体的,可以看作一个字母来进行反转,
比如说,(abc(de)),反转后应该是((de)cba),所以左边找括号右边找括号+反转/不反转括号内的数,O(n)的那种想法是不可行的
(怎么感觉可能也就我这么zz发现不了不可行了……)
这里正确的解法是DFS+括号匹配,直接贴代码吧,不是什么特别难以理解的问题
#include<bits/stdc++.h> using namespace std; const int MAX=5e6+5; string s; int pos[MAX],L[MAX],R[MAX]; void dfs(int l,int r,int flag) { if(!flag) //第偶数个括号内,不反转,正向输出 { for(int i=l;i<=r;i++) { if(s[i]!='(') cout<<s[i]; else //碰到第奇数个括号,更新输出区间范围为下一个括号内的字符串位置 {dfs(i+1,R[i]-1,1);i=R[i];} } } else //第奇数个括号内,反转,逆向输出 { for(int i=r;i>=l;i--) { if(s[i]!=')') cout<<s[i]; else //碰到第偶数个括号 {dfs(L[i]+1,i-1,0);i=L[i];} } } } int main() { cin>>s; int cnt=0; for(int i=0;i<s.length();i++) { if(s[i]=='(') pos[++cnt]=i; //用一个栈来记录括号的位置 else if(s[i]==')') { R[pos[cnt]]=i; //对左右括号的位置进行匹配 L[i]=pos[cnt--]; } } dfs(0,s.length()-1,0); return 0; }