答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。
输入样例
8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
输出样例
YES
YES
YES
YES
NO
NO
NO
NO
题目分析
这道题需要按题目要求一个个分析(感觉考虑的有点麻烦,可以直接看结论):
1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
即出现P、A、T以外的字符均不正确
2.任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
若字符串正确,则P,T只能出现一次,P后必跟着A
x=x,即若PAT左侧的x由n个A组成,那么PAT右侧的x也一定是由n个A组成
3.如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
P、T间可以是由数个A组成的字符串,但是必须至少有一个A
结合2,3条(假设此时字符串已是A…PA…TA…的形式):
- 可以设立三个整型变量,分别记录P前A的数量a’,P、T之间的A的数量b’,T后A的数量c’;
- 若想aPbTc是正确的,首先b必须是至少由一个A组成的字符串,即b’≥1。当b’=1时,a’=c’;
- 假设有两个字符串M和N,M的a’=a1,b’=b1,c’=c1,N的a’=a2,b’=b2,c’=c2,M符合aPbTc形式,且a1=a2,b2=b1+1,c2=a1+c1,则N也正确
可以进行一下简单的推算:
由最简单的形式开始:aPATc,此时b’=1,a’=c’;(初始的a’,b’,c’,后用(初)a’的形式指代这里的a’,b’,c’)
若aPATc正确,则aPAATca正确,新的字符串a’=(初)a’,b’=2,c’=(初)c’+(初)a’=2(初)a’
此时aPAATca正确,则aPAAATcaa也正确,新的字符串a’=(初)a’,b’=3,c’=(上一个字符串的)c’+(初)a’=2(初)+a’(初)a’=3(初)a’
可以经行多次想上次的推算
由此可以推出结论:
只要a’*b’=c’且b’>0即可 满足2、3条件(a’、b’、c’均指现在的字符串的a’、b’、c’a)
根据这几条限定要求,我完成了下面的代码,给大家做个参考:
#include<iostream>
#include<map>
using namespace std;
bool fun(string s,int len)//判断字符串是否有P、A、T以外的字符
{
for(int i=0;i<len;i++)
{
if(s[i]!='P'&&s[i]!='A'&&s[i]!='T')
return 0;//字符串中出现了非P、A、T的字符
}
return 1;//字符串完全由P、A、T构成
}
int main()
{
int n;
cin>>n;
while(n--)
{
string s;
map<char,int> m;//记录每个字符出现的次数
int a,b,c,len;//a=P前A的数量,b=PT间A的数量,c=T后A的数量
cin>>s;
len=s.length();
if(!fun(s,len))//字符串中出现了非P、A、T的字符
{cout<<"NO"<<endl;
continue;}
for(int i=0;i<len;i++)
{
m[s[i]]++;//s[i]的字符的数量+1
if(s[i]=='P')//由条件2可得,字符串中只能出现一个P,即P出现了就可以求得a的值
a=i;//a的值同样代表了P出现的数组标号
if(s[i]=='T')//由条件2可得,字符串中只能出现一个T,即T出现了就可以求得b,c的值
{
b=i-a-1;//i此时等于T出现的数组编号,a等于P出现的数组编号
c=len-i-1;
}
}
if(m['P']!=1||m['T']!=1)//P、T出现的次数不为1
{cout<<"NO"<<endl;
continue;}
if(c==a*b&&b>0)
cout<<"YES"<<endl;
else
{cout<<"NO"<<endl;
continue;}
}
return 0;
}