“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
输入样例:
8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
这是今天我在pat上刷乙级题是遇到的一个让我苦手的一道题,无论如何都不能完美全对通过,后来在搜索引擎上搜了与这道题相关的一些资料,才发现我对这道题的理解就没有到位,比如说三个条件我的分析就是完全错误的,正确的分析应该是这样:首先根据条件1,字符串中只能有’P’、’A’、’T’三种字符,这是很好理解的,条件2也非常好理解,不再赘述,最主要的是条件3、这是我认为本题最关键的地方,正是因为我没有解读正确,才会解题出错,第三个条件需要用递归的思维去理解、比如说,如果aPbTc是正确,根据前两个条件,意味着b只能是A,否则,aPbTc是会出错的,而且,a=c,确立了b、a、c,就可一看后面的结论,aPAATca也是正确的,那么如果aPAATca是正确的,就可以推出aPAAATcaa是正确的,再往后以此类推,最后会发现一个规律,那就是:假设x1是a字符串中a的个数,x2是P与T之间字符串的个数,x3是T之后的A的个数,可以得到一个公式,那就是x3 = x2 * x1,条件2也适用于这条公式。弄清楚原理就可以开始写代码了,下面贴一下我写的代码:
#include <iostream> #include <string> using namespace std; int main() { int n; cin >> n; getchar(); string lines[10]; string results[10]; for (int i = 0; i < n;i++) { getline(cin, lines[i]); } for (int i = 0; i < n; i++) { int length = lines[i].length(); int idxP = lines[i].find(‘P‘, 0); int idxT = lines[i].find(‘T‘, 0); //根据题意,把字符串中不包含‘P‘‘T‘以及P与T //相邻以及P在T之后的情况排除 if(idxP == string::npos||idxT==string::npos||idxP+1>=idxT) { results[i] = "NO"; }else { //把a,b,c从字符串中剥离开来 string a(lines[i],0,idxP); string b(lines[i], idxP + 1, idxT - idxP - 1); string c(lines[i], idxT + 1,length-idxT-1); string temp = a + b + c; if (temp.find_first_not_of(‘A‘) != string::npos) { results[i] = "NO"; }else { if(idxP*(idxT-idxP-1) == length-idxT-1) { results[i] = "YES"; }else { results[i] = "NO"; } } } } for (int i = 0; i < n;i++) { cout << results[i] << endl; } return 0; }