1003 我要通过!
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1)字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符; 2)任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串; 3)如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (≤10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。
输入样例:
10
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
APATTAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO
分析:本题共三条语法规则:
1)字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
2)任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
这意味着P和T两个字符有且只能有一个,其余字符则必须是A
3)如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
因此可以将复杂的串简化后判断
由于P和T数量确定,且在文法简化中也不会变化,唯一变化的字符A的数量,因此可以不用在字符串上面修改,可以记录A的数量并作为判断依据。
P和T将字符串分割为三个部分,使用三个变量记录三个部分A的数量,则2)和3)文法规则可以通过判断A的数量实现:
2)如果中间部分A的数量为0,则显然不合要求。为1,如左右两边的A数量相当,则符合xPATx形式,通过。
3)如果中间部分的A数量大于1,则按照文法转换字符串直至中间只有一个A,即aPATb的形式,然后使用规则2)判断
#include<iostream>
#include<cstring>
using namespace std;
bool judgestr(string s) {
int length = s.size();
int leftAnum = 0, rightAnum = 0, midAnum = 0;
int Ppos, Tpos, Pnum=0, Tnum=0;
for (int i = 0;i < length;i++) {
if (s[i] != 'P' && s[i] != 'A' && s[i] != 'T')
return false;
if (s[i] == 'P') {
Ppos = i;
Pnum++;
if (Pnum > 1)
return false;
}
if (s[i] == 'T') {
Tpos = i;
Tnum++;
if (Tnum > 1)
return false;
}
}
leftAnum = Ppos;
midAnum = Tpos - Ppos - 1;
rightAnum = length-Tpos - 1;
if (midAnum == 1) {//已经是最简形式
if (leftAnum == rightAnum)
return true;
else return false;
}
//含有xPATx则通过
while (midAnum > 0 && rightAnum >= leftAnum) {
//含有aPbATc的,进行转换,即使a是空串也不会死循环
if (midAnum == 1) {
if (leftAnum == rightAnum)
return true;
else return false;//判断最简形式含有xPATx则通过
}
else {
rightAnum -= leftAnum;
midAnum--;
}
}
return false;
}
int main() {
int number;
cin >> number;
string str[11];
for (int i = 0;i < number;i++) {
cin >> str[i];
}
for (int i = 0;i < number;i++) {
if (judgestr(str[i])) {
cout << "YES" << endl;
}
else cout << "NO" << endl;
}
return 0;
}