说实话,这道题还是很难的,我记得我第一次做的时候,题目都没读懂。到后来看了一遍解析之后再做,还是心有余悸。
首先三个条件:
1.
只
包
含
P
A
T
三
个
字
符
\color{red}1.只包含PAT三个字符
1.只包含PAT三个字符
所以遍历一遍,把包含其他字符的字符串直接输出NO
2.
形
如
x
P
A
T
x
的
是
正
确
的
答
案
,
x
为
空
或
者
仅
由
A
组
成
。
\color{red}2.形如xPATx的是正确的答案,x为空或者仅由A组成。
2.形如xPATx的是正确的答案,x为空或者仅由A组成。
这个条件的理解是P和T只出现一次,且P在T的左边,两者中间隔了一个A,而且左右两个x的长度相同且仅由A组成。
3.
如
果
a
P
b
T
c
是
正
确
,
那
么
a
P
b
A
T
c
a
也
是
正
确
的
。
其
中
a
,
b
,
c
均
或
者
是
空
字
符
串
,
或
者
仅
由
A
组
成
。
\color{red}3.如果aPbTc是正确,那么aPbATca也是正确的。其中a,b,c均或者是空字符串,或者仅由A组成。
3.如果aPbTc是正确,那么aPbATca也是正确的。其中a,b,c均或者是空字符串,或者仅由A组成。
这个条件的理解是:aPbTc要正确,则只能从条件2得来,所以aPbTc必须满足xPATx,也就是说b要等于A且a==c即aPATa,而aPbATca成立,在中间加上了一个A,在末位加上P前面a的长度。如果记P前面的长度为x,P和T之间的长度为y,T后面的长度为z(都不包含边界)。那么满足中间增加一个A的长度时,后面增加x的长度,才能满足是成立的字符串。
如果逆向思考,把一个字符串缩短,即z-x同时y-1后也是成立的字符,直到最后y=1而此时应该满足x==z
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
int main(){
int n;
cin>> n;
string str;
getchar();
while(n--){
getline(cin, str);
int nump = 0, numt = 0, others = 0;
int locp = -1, loct = -1;
for(int i = 0; i < str.size(); i++){
if(str[i] == 'P') nump++, locp = i;
else if(str[i] == 'T') numt++, loct = i;
else if(str[i] != 'A') others++;
}
if(nump != 1 || numt != 1 || (loct - locp <= 1) || others != 0){
cout<<"NO"<<endl;
continue;
}
int x = locp, y = loct - locp - 1, z = str.size() - loct - 1;
if(x != z - x*(y - 1)){
cout<<"NO"<<endl;
}else cout<<"YES"<<endl;
}
return 0;
}