PAT B1003 我要通过

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值