题目描述:
答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符; - 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串; - 如果
aPbTc
是正确的,那么aPbATca
也是正确的,其中a
、b
、c
均或者是空字符串,或者是仅由字母A
组成的字符串。
思路:
思路一:我最初的思路是想着用Java里面的正则表达式来进行模式匹配解这道题,但是由于仅仅只想到了处于三个不同位置A的位置关系,并没有考虑到数量关系,因此最终的答案仅仅是部分正确。如果有人使用正则表达式被AC的,可以互相分享一下。
思路二:第二个思路就是和网上大部分一样的,通过结合第二,和第三个条件来考虑处于三个位置A的数量关系。下面就来详细的推导一下三个位置A的数量有什么关系。这道题的难点在于题目条件并没有直接给你太直白的规律,需要你从第2,3条件中找规律。
推导过程:
记P之前A的数目为f_A,P和T之间A的数目为m_A,T之后A的数目为l_A。
(1)对于条件2
- 任意的xPATx的字符串都是正确的,即x为空时,即PAT是正确的,此时f_A=0,m_A=1,l_A=0;
- x为A时,即APATA是正确的,此时f_A=1,m_A=1,l_A=1;
- x为AA时,即AAPATAA是正确的,f_A=2,m_A=1,l_A=2;
- 依次类推,无论x为多少,此时f_A和l_A是相等的,而m_A=1》于是可以猜想:f_A=m_A*l_A或者l_A=m_A*f_A;
(2)结合条件2和3
- 由(1)可知,PAT是正确的,此时a,c取空,b取A,那么PAAT也是正确的,此时f_A=l_A=0,m_A=2;满足上述两个假设;同理PAAT正确时,此时a,c取空,b取AA ,那么PAAAT也正确;以此类推PAAAAT,PAAAAAAT.....都是正确的。
- 若APATA是正确的,此时a,b,c均取A,那么APAATAA是正确的,此时f_A=1,m_A=2,l_A=2,满足l_A=m_A*f_A;同理既然APAATAA是正确的,根据条件3,APAAATAAA是正确的,此时f_A=1,m_A=3,l_A=3,满足l_A=m_A*f_A;以此类推,APAAAATAAAA,APAAAAATAAAAA......均正确。
- 若AAPATAA是正确的,那么结合条件3,AAPAATAAAA是正确的,此时此时f_A=2,m_A=2,l_A=2,满足l_A=m_A*f_A;
综上所述,我们可以得出的结论是:三个位置A的数目满足一定的数量关系,即l_A=m_A*f_A。如果能找到这个规律,那么这道题就变得很容易,利用C或者Java或Python都很容易的写出答案。
代码:
#include<iostream>
#include<string>
using namespace std;
string YesOrNo(string str)
{
int front_A=0;
int mid_A=0;
int last_A=0;;
int i=0;
string YES="YES";
string NO="NO";
while(i<str.size()&&str[i]=='A')
{
front_A++;
i++;
}
if(str[i]=='P')
{
i++;
while(i<str.size()&&str[i]=='A')
{
mid_A++;
i++;
}
if(mid_A==0) return NO;
}else{
return NO;
}
if(str[i]=='T')
{
i++;
while(i<str.size()&&str[i]=='A')
{
last_A++;
i++;
}
}else{
return NO;
}
if(last_A==mid_A*front_A) return YES;
else return NO;
}
int main()
{
string str;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>str;
cout<<YesOrNo(str)<<endl;
}
return 0;
}