CF1494A

CF1494A ABC String

宣传博客

题目大意:

输入一串有\(A,B,C\)的字符串,把\(A,B,C\)分别定义为 "(" 或 ")",判断转换之后字符串是否合法。

解题思路:

读懂题目后,很容易就想到括号匹配这一道题,这道题的前置知识就是这个。

假设\(b\)为括号序列,括号匹配代码:

queue<char> q;
bool check(){//括号匹配
    while(q.size()) q.pop();//清空队列
    for(int i=1;i<=len;i++){
        if(b[i]=='(') q.push(b[i]);//左括号加入队列
        else if(b[i]==')'){//右括号排出
            if(q.size()) q.pop();//有左括号,匹配成功
            else return false;//如果没有左括号,就说明匹配失败
        }
    }
    if(q.size()) 
        return false ;//右括号多了,匹配失败
    else  
        return true;
}

对于\(A,B,C\)对应括号进行枚举,一共有六种情况(不可能三个都是一样的括号,排除两种),虽然也能过,但是我们要思考更多的性质。

正确解法:

首先,如果首端和末端两个字符一样,那么括号也一样,是肯定不能匹配上的。

此外,如果字符串长度为奇数,那么肯定不能匹配(易得)。

我们假设字符串\(a\)为给定的\(A,B,C\)序列,\(len\)\(a\)的长度,那么上面两个性质可以表示成:

scanf("%s",a+1);
if(a[1]==a[len]&&len%2){
    cout<<"NO"<<endl;
}

我们知道,要想匹配上,第一个字符对应的肯定是左括号"(",最后一个字符肯定是右括号")"。那么我们就已经确定了两种字母对应的括号是什么了。

现在,只需要枚举另外一种字符对应的括号,形成新的括号序列,对两种情况分别进行检查(括号匹配知识),判断是否合法就可以了

代码:

#include<bits/stdc++.h>
using namespace std;
queue<char> q;
int T,len;
char a[55],b[55];

bool check(){//括号匹配
    while(q.size()) q.pop();//清空队列
    for(int i=1;i<=len;i++){
        if(b[i]=='(') q.push(b[i]);//左括号加入队列
        else if(b[i]==')'){//右括号排出
            if(q.size()) q.pop();//有左括号,匹配成功
            else return false;//如果没有左括号,就说明匹配失败
        }
    }
    if(q.size()) 
        return false ;//右括号多了,匹配失败
    else  
        return true;
}

int main()
{
    cin>>T;
    while(T--){
        scanf("%s",a+1);
        bool flag=false; 
        len=strlen(a+1);
        if(len%2||a[1]==a[len]){
            cout<<"NO"<<endl;
            continue;
        }
        b[1]='(';b[len]=')';//检查用(其实也可以去掉)
        for(int k=1;k<=2;k++){ 
            for(int i=2;i<len;i++){
                if(a[i]==a[1])        b[i]='(';
                else if(a[i]==a[len]) b[i]=')';
                //两种情况
                else if(k==1)         b[i]='(';
                else                  b[i]=')';
            }
            flag=check();//检查
            if(flag) break;
        }
        if(flag) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

快乐的切掉这道题!!

posted @ 2021-03-09 16:36  Evitagen  阅读(79)  评论(1)    收藏  举报