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;
}
快乐的切掉这道题!!
不关注的有难了😠😠😠https://b23.tv/hoXKV9

浙公网安备 33010602011771号