题目分析:
这道题,挺无奈的,说难也难说简单也简单,刚开始理解错了WA了一发,后来注意到题目给的最后一个测试例子,才明白自己回错了意。解这道题的关键是要理解题目真正想表达的意思,有点考阅读理解和细致思考的感觉。
题目重点在于第二和第三个条件如何理解:
- 对于第二个条件要注意到:x是一个字符串,因此 xPATx,就意味着PAT左右两侧的字符串必须相同,要么都是空字符串,即没有,要么都是A组成的串,那么除了判断是不是都是A外还需要判断长度是否相等。
- 对于第三个条件,还需要多琢磨一下。如果aPbTc是正确的,可以继续递推出aPbATca也正确,那么重要的是确定这个递推关系式的起点,稍加思考便能明白,这个起点就是xPATx的情况,也即满足条件二的情况。因此,第三种判定符合的方法实际上是从第二类条件满足的基础上衍生出来的。每次递推,P和T之间可以多插入一个A,对应的要求T后的字符串多出一个a字符串来。
以
分别表示a,b,c串,
分别表示P左边的字符串,P、T之间的字符串以及T之后的字符串,那么可得等式:
而初始条件要求
因此
故可以用下面的代码实现(已AC)
源代码
#include <stdio.h>
bool isPAT(int *ch,int len);
int main()
{
int caseNumber;
scanf("%d",&caseNumber);
getchar();
while(caseNumber--){
int ch[100];
int count=0;
while((ch[count++]=getchar())!=EOF&&ch[count-1]!=10) //读取字符,10对应换行符
;
if(isPAT(ch,count-1)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
bool isPAT(int *ch,int len)
{
int i=0;
int left=0,mid=0,right=0; //分别记录P前遇到,P与T之间以及T之后的A个数
int symP=(int)'P',symA=(int)'A',symT=(int)'T';
while(ch[i]!=symP){ //循环 直到遇到P
if(ch[i]!=symA) return false;
if(i++>len-4) return false; //倒数第三个字符还未遇到P,不能产生PAT
left++; //对P左边的A个数计数
}
if(ch[++i]!=symA) return false; //P之后不是A,返回错误
mid++;
while(ch[++i]!=symT){
if(ch[i]!=symA) return false;
if(i>len-2) return false; //数组末尾还未遇到T,返回错误
mid++;
}
while(++i<len){ //若后面还有数字
if(ch[i]!=symA) return false;
right++; //对T后面的A计数
}
if(mid==1){
if(left!=right) return false; //对于xPATx型,若两端A个数不等,返回错误
}
else if(right!=mid*left) return false;
return true;
}