1003 我要通过! (20分)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符; - 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串; - 如果
aPbTc
是正确的,那么aPbATca
也是正确的,其中a
、b
、c
均或者是空字符串,或者是仅由字母A
组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 (),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES
,否则输出 NO
。
输入样例:
8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
解题思路:这道题的语文水平实在是太迷惑了……看了半天也没看出来啥意思。看了别人的总结我想我估计这辈子都想不出来……在1、2、3条中找的规律是:
对P前、PT中间、T后的字符串长度设为a、b、c,那么:a*b = c。
对于2,满足2的a=c,b=1,故a*b =c。
这个有一个前提是b必须至少为A,因为3的前提是2,所以aPbTc成立的前提是aPbTc可以形如xPATx,这是3的意思,所以b=1,而a=c,又回到2,在2的基础上对3进行扩充,得到的是:c=a+c=2*a,b=2,所以a*b = a*2 = 2*a = c。同理,当此情况的aPbTc成立时,aPbATca又可成立,即b=3,a*b = a*3 = 3*a = c……
理解完算式,用一些判断条件提前退出循环,对最后的a、b、c的算式关系进行检查即可。
这道题的难点应该是3里的这一句:
如果
aPbTc
是正确的,那么aPbATca
也是正确的
AC代码:
#include <iostream> #include <string> using namespace std; bool check(string s) { string a, b, c; int posA=0, posB=0, posC=0; bool isP = false, isT = false; for (int i = 0; i < s.size(); i ++ ) { if (s.c_str()[i] != 'A' && s.c_str()[i] != 'T' && s.c_str()[i] != 'P') return false; if (s.c_str()[i] == 'P') { //P前面的子串 a = s.substr(0, i); posA = i; if (isP) return false; isP = true; } if (s.c_str()[i] == 'T') { //P和T中间的子串 b = s.substr(posA + 1, i - posA - 1); posB = i; if (isT) return false; isT = true; } } if (posB < posA) return false; //T不能在A前面 c = s.substr(posB + 1, s.size() - posB - 1); //T后面的子串 if (b.length()*a.length() == c.length() && b.length() >= 1) //相等为0,不等为-1 return true; else return false; } int main() { int N; cin >> N; for (int i = 0; i < N; i++) { string s; cin >> s; printf(check(s)?"YES":"NO"); } }
小Tips:
1.string.compare()相等为0,不相等为-1。
2.string.substr(pos,length),第一位为起始位置,第二位为裁剪长度。
3.for(auto c : string)得到的c是字符。
0 条评论