题目
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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三个字母组成。所以判断字符串里有其他字符出现就答案错误。
2、“PAT”的左右为空或者左右的“A”的数量相同,则答案正确。
3、第三个条件是以第二个条件为基础的。把条件二代入条件三,即“若xPATx”正确,则“xPAATxx”正确,即“xPAAATxxx”正确,即“xPAAAATxxxx”正确……可以得出规律:“P”前面的“A”的数量与“P”“T”之间的“A”的数量相乘等于“T”后面的“A”的数量。
所以我将“P”前面“A”的数量累加到a,“P”“T”之间“A”的数量累加到b,“T”后面的“A”的数量累加到c。
然后判断a*b=c时答案正确。
根据三个条件还能得出几个没有明确指出的隐藏条件:
“P”、“T”必须出现,且只能出现一次,出现的顺序一定是“P”在“T”的前面。
“P”、“T”中间一定要出现过“A”,即,b>0。
我第一次提交时测试点1一直没通过,想了很久才发现忘记判断T是否存在了,导致输入AP会输出YES。
AC代码
#include<iostream>
#include"stdio.h"
#include"math.h"
#include"string.h"
using namespace std;
int main(){
int a,b,c;
int i,j,l;
char s[110];
int k,n,m,r;
while(cin>>k){
getchar();
for(j=0;j<k;j++){
cin>>s;
l=strlen(s);
a=0;b=0;c=0;
n=0;m=0;r=0;
for(i=0;i<l;i++){
if(s[i]!='A'&&s[i]!='P'&&s[i]!='T'){
r=1;break;
}else if(s[i]=='A'){
if(n==0) a++;
else if(n==1&&m==0) b++;
else if(n==1&&m==1) c++;
}else if(s[i]=='P'){
if(n==0) n=1;
else{
r=1;break;
}
}else if(s[i]=='T'){
if(n==0){
r=1;break;
}else if(n==1&&m==0) m=1;
else if(n==1&&m==1){
r=1;break;
}
}
}
if(n!=1||m!=1) r=1;
if(b==0) r=1;
if(r==1) cout<<"NO"<<endl;
else if(b!=0&&a*b==c) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
return 0;
}
思路优化
我的a、b、c是遍历字符串数组然后累加进去的。
看到很多大佬都是直接记录字符串数组里P、T的位置,代码要简洁的多。