问题描述
问题分析
Condition 1:
·在字符串中只能出现P、T、A三个字母,其他任何字母都不能出现。
Condition 2:
·形如xPATx可以正确,必须保证前后字符相等,如果是空格就都是空格,如果是A就都是A,并且数目必须相同。
Condition 3:
·这个条件相对来说是最复杂的,我们一点一点分析:
如果aPbTc正确,则aPbATca成立。
我们思考一下什么情况下aPbTc会成立。根据第一个条件
我们知道a,b,c不可以为除了P、T、A之外的任何字符根据第二个条件,b = ‘A’且a=c可以成立
即为APATA,AAPATAA,空PAT空,等等都可以成立。
我们知道c和a字符串一定相等,所以如果APATA成立,则APAATAA成立,继续类推AAPAATAAAA成立,以此类推...
接着,我们已经推出了APAATAA成立,所以APAAATAAA成立,APAAAATAAAA成立.....
如果大家继续往下推会发现一个很神奇的规律,由于末尾是ca,且c与a相等
所以末尾的A数字会不断堆叠,且增加的个数是开头a的个数,所以后面的数字一定是前面数字的倍数。
那么应该是多少倍呢?经过推导我们发现,因为aPbTc->aPbATca中间每次会多加一个A
所以后面的字符数是和P与T中间的A数相同速度增加的
因此我们得出结论,P与T之间的A字符数目 = T之后的字符数目 / P之前的字符数目
前两个条件很容易实现,第三个问题经过分析得出结论以后,也很容易实现,我们只需要记录P的位置和T的位置,然后就可以求解出P与T之间的A数目,T后面字符数目,P前面的字符数目。然后表示出条件三即可。
代码
#include <iostream>
#include <string>
using namespace std;
void isPAT(string str);
int main() {
int n(0); // 字符串个数
cin >>n;
for(int i=0;i<n;i++){
string temp;
cin >> temp;
isPAT(temp);
}
return 0;
}
void isPAT(string str){
int P_j(0),T_j(0); //记录P,T的位置
int countP(0), countT(0); //记录P,T的个数
bool status= true; // 当有不合法的字符出现时变为false
for(int i=0;i<str.length();i++){
//有不是P,A,T三种字符的输出NO
if(str[i]!='P' && str[i]!='A'&& str[i]!='T'){
status = false;
}
if(str[i]=='P'){
P_j=i;
countP++;
}
if(str[i]=='T'){
T_j=i;
countT++;
break;
}
}
if((T_j-1-P_j)>=1 && P_j*(T_j-1-P_j)==(str.length()-1-T_j) && countP==1 && countT==1 && status){
cout << "YES" << endl;
}
else{
cout << "NO" << endl;
}
}
总结
答题用时15min
Q3——finish√