codeforces1469A Regular Bracket Sequence(贪心)

传送门
关键思路:见了这种括号匹配的题,一是想栈,二是把见了左括号想成 + 1 +1 +1,见了右括号想成 − 1 -1 1,从左向右特判每一位上的前缀和是不是 > = 0 >=0 >=0,以及最后一位的前缀和是不是 = 0 =0 =0
题解:因为给出的字符中只有一个左括号和右括号,字符总长度为 ∣ s ∣ |s| s,那么必然要将 ∣ s ∣ − 2 |s|-2 s2个问号替换,因为这个字符串最后要匹配,也就是说比如见了左括号为 + 1 +1 +1,右括号为 − 1 -1 1,那么必然到了每位上都不能为负值,为负值说明右括号多了呀,所以一种方法就是将前 ∣ s ∣ / 2 − 1 |s|/2-1 s/21个问号全部替换为左括号,其余的问号全部替换为右括号,最后特判一遍即可。

    rush(){
    
    
        cin>>ori;
        int len=ori.size(),cnt=len/2-1;
        rep(i,0,len-1)ori[i]=(ori[i]!='?')?ori[i]:((cnt--)>0?'(':')');
        int tmp=0;
        bool flag=true;
        rep(i,0,len-1){
    
    
            tmp+=ori[i]=='('?1:-1;
            if(tmp<0)flag=false;
        }
        if(tmp!=0)flag=false;
        printf("%s\n",flag?"YES":"NO");
    }

说下我的做法,我刚开始瞎看了一眼,没注意到题中说只有一个左括号和一个右括号,我以为有很多个左括号、右括号和问号,看了一眼数据范围 ∣ s ∣ < 100 |s|<100 s<100,思路还是搞成 + 1 , − 1 +1,-1 +11那种方法,那么也就说到了问号需要抉择是弄成左括号还是右括号呢,如果全部是左括号,最终无非就是到了 100 100 100,也就说到了每一位上能取到的值都在 200 200 200以内,那么循环数组处理下到了每一位上到底能取哪些值,见了左括号 + 1 +1 +1,见了右括号 − 1 -1 1,见了问号分别处理 + 1 +1 +1 − 1 -1 1,最终特判即可

string s;
const int N=1e2+5;
int tmp[2][205];
int main(){
    
    
    #ifdef io
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    rush(){
    
    
        cin>>s;
        int len=s.size();
        bool flag=true;
        rep(i,-100,100)tmp[0][i+100]=tmp[1][i+100]=0;
        tmp[0][100]=1;
        rep(i,1,len){
    
    
            int now=i%2,up=(i-1)%2;
            rep(j,-100,100)tmp[now][j+100]=0;
            if(s[i-1]=='('){
    
    
                rep(j,0,100){
    
    
                    if(tmp[up][j+100])tmp[now][j+1+100]=1;
                }
            }else if(s[i-1]==')'){
    
    
                int ff=0;
                rep(j,1,100){
    
    
                    if(tmp[up][j+100])tmp[now][j-1+100]=1,ff=1;
                }
                if(!ff){
    
    
                    flag=false;
                    break;
                }
            }else{
    
    
                rep(j,-1,100)if(tmp[up][j+100])tmp[now][j+1+100]=1;
                rep(j,1,100)if(tmp[up][j+100])tmp[now][j-1+100]=1;
            }
        }
        if(!tmp[len%2][100])flag=false;
        printf("%s\n",(flag?"YES":"NO"));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/112172035