“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
- 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
- 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
输入样例:
8PATPAATAAPATAAAAPAATAAAAxPATxPTWhateverAPAAATAA
输出样例:
YESYESYESYESNONONONO 分析: 关于上面正确字符串的定义, 这是典型的递归定义, 第1点和第2点是初始条件, 第3点是归纳条件. 来说下显然可以得到的结论, 正确字符串必定有且只有一个P和一个T, 其余的都是A, 并且P在T的前面, 更具体地, 正确字符串必定是A...APA...ATA...A的模式. 仔细观察第3点, aPbATca和aPbTc的区别在于前者的P和T之前多了个A, T之后多了a, 可以想象, 面对一个给定字符串, 先要数出P之前有多少个A, P和T之间有多少个A, T之后有多少个A, 首先判断是否符合第2点, 不符合就在T之后去掉与P之前相同数量的A, 在P和T之间去掉一个A, 然后再判断剩下来的字符串是否为正确字符串, 重复若干次去掉的操作, 最后肯定归结到是否符合第2点. 但是有更好的办法, 既然每次都是去掉一个中间A和一个尾部a, 想象最后得到的aPATa形式, 将P前面A的数量设为x, P和T之间A的数量设为1, 那么每增加一个中间A就增加一个尾部a, 假设增加y次得到给定的字符串. 对于给定的字符串, P前面A的数量仍为x, P和T之间A的数量变为1+y, T之后A的数量变为x+xy=x(1+y), 那么给了一个字符串, 判断 中间A的数量 是否大于0而且 T之后A的数量 是否等于 P前A的数量 乘以 P和T之间A的数量 就可以了. 接着上代码:
#include#include #include #include using namespace std;const string rightAnswer = "YES";const string wrongAnswer = "NO";bool isRight(string s){ // count len_front_A_string size_t index_of_A = 0; while(index_of_A 0 && len_front_A_string*len_middle_A_string==len_back_A_string) { return true; }else { return false; }}int main(){ //freopen("input.txt", "r", stdin); int n; cin>>n; string inputStr; for(int i=0;i >inputStr; if(isRight(inputStr)) { cout< <