首先理解题目:
第一个条件:
判断字符串中是否仅有 ‘P’,‘A’, 'T’这三种字符,包含其他字符就错误
第二个条件:
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字符’A’组成的字符串;
那么正确的有这些:
PAT
APATA
AAPATAA
AAAPATAAA
就是中间一个’A’左右加上等量的’A’(不加也可以)都是正确的。
难以理解的是第三个条件:
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
乍一看感觉蒙蒙的,那我们先代入看看,找正确字符串的代入aPbTc:
PAT —— 对于 aPbTc 来说ac是空,b是’A’。所以 PAAT 是正确的。类推出PAAAAAT中间加多少个A都是正确的
APATA —— 对于aPbTc来说,abc都是’A’。所以 APAATAA 是正确的。再类推一下,那么 APAAATAAA 是正确的。
AAPATAA —— 对于aPbTc来说,a和c是’‘AA’’,b是’A’。所以AAPAATAAAA是正确的,再类推一下,AAPAAATAAAAAA 是正确的。
推理——开头的’A’的个数 * 中间的’A’的个数 = 结尾的’A’的个数
我们结合三个条件中就能看出规律:字符串中只能有一个’P’一个’T’,且’P’要在’T’之前,中间末尾和开头可以插入’A’。
插入’A’的条件是:
- (1)
(开头的’A’的个数 )乘以 (中间的’A’的个数) 等于(结尾的’A’的个数) - (2)
’P’和’T’两端没有’A’,中间只要有’A’就可以('A’的个数不是0就可以)
满足两者任意一个条件,字符串就正确
实质上,本题考察的是对字符串的操作,但是题目难于理解。遇到这类题目,我建议在草稿纸上划出字符串的种种形式,慢慢往下推理,就能快速找到规律
下面是实操代码,不太清楚的地方欢迎评论区讨论
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
bool isRight(string str){ //判断传入的字符串是否正确 ,传入的参数是所需判断的字符串
int len=str.length();
int a=0,b=0; //辅助变量 ,a表示字符'P'的个数,b表示字符'T'的个数
for(int i=0;i<len;++i){ //遍历字符串
if(str[i]=='P'||str[i]=='T'||str[i]=='A'){ //判断字符只能是'P','A','T'的组合
if(str[i]=='P'){ //统计'P'的个数
++a;
}
if(str[i]=='T'&&(a!=0)){ //统计'P'之后'T'的个数
++b;
}
if(str[i]=='T'&&(a==0)){ //如果'T'在'P'之前就返回false
return false;
}
}else{ //含有别的字符,直接返回false
return false;
}
}
if(a==1&&b==1){ //限制字符串仅含一个'P'和一个'T',且'P'在'T'之前
int c=0,d=0,e=0; //辅助变量
for(int i=0;i<len;++i){ //重新统计abcde的值
if(str[i]=='P'){
++a;
}
if(str[i]=='T'){
++b;
}
if(str[i]=='A'&&a==1){ //c表示字符串中'P'之前'A'的个数
++c;
}
if(str[i]=='A'&&a==2&&b==1){ //d表示字符串中'P'和'T'之间'A'的个数
++d;
}
if(str[i]=='A'&&a==2&&b==2){ //e表示字符串中'T'之后'A'的个数
++e;
}
}
if((c==0&&e==0&&d!=0)||(c*d==e&&d!=0)){ //前半句表示只有'P'和'T'之间有'A'且必须有,后半句的d!=0用于排除字符串就是PT的情况
return true;
}
}
return false;
}
int main(){
int n=0;
while(scanf("%d",&n)!=EOF){ //循环输入数字
string str[n]; //声明字符串数组
for(int i=0;i<n;++i){
cin>>str[i]; //这里使用标准库cin给字符串数组赋值 (这里有一个疑问,使用scanf函数怎么给字符串数组赋值)
}
for(int i=0;i<n;++i){ //循环判断字符串数组中每个字符串是否正确
if(isRight(str[i])){ //调用判断函数
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
}
return 0;
}
码字不易,记得点赞哦~