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;
}
原文地址:https://www.cnblogs.com/Egoist-/p/8361526.html