題目描述:
答案正確”是自動判題系統給出的最令人歡喜的回覆。本題屬於 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;
}