PAT B1003. 我要通过!(20)

原文链接: PAT B1003. 我要通过!(20)

上一篇: PAT A1101. Quick Sort (25)快排主元个数

下一篇: PAT B1019. 数字黑洞 (20)

1003. 我要通过!(20)

https://www.patest.cn/contests/pat-b-practise/1003

时间限制

400 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

CHEN, Yue

答案正确 ”是自动判题系统给出的最令人欢喜的回复。本题属于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

分析:

任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
那么正确的有这些:
PAT
APATA
AAPATAA
AAAPATAAA
…不说了,就是中间一个A左右加上等量的A(不加也行)都是正确的。

如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
拿上面的那几个正确的举例子,那么正确的有这些:
PAT —— 对于 aPbTc 来说ac是空,b是A。所以 PAAT 是正确的。同理PAAAAAT中间加多少个A都是正确哒~
APATA —— 对于aPbTc来说,abc都是A。所以 APAATAA 是正确的。再类推一下,那么 APAAATAAA 是正确的。
AAPATAA —— 对于aPbTc来说,a和c是AA,b是A。所以AAPAATAAAA是正确的,再类推一下,AAPAAATAAAAAA 是正确的~
所以说规律就是,可以在P和T中间加A并且在T后面加A,要求必须是,中间加上一个A,末尾就得加上几倍的(P前面A的那个字符串)。换句话说就是,中间的A的个数如果是3,那么末尾的A的个数就得是开头A的个数的3倍。很巧,当中间A为一个的时候,末尾和开头A的个数必须相等正好是第二条的要求~~~

所以一句话总结字符串的要求:只能有一个P一个T,中间末尾和开头可以随便插入A。但是必须满足开头的A的个数 * 中间的A的个数 = 结尾的A的个数

所以检验的时候,让i停留在出现P的地方,然后让k停留在字符串里面T的地方,那么len – 1 – k就是T后面的A的个数,k – 1 – i就是P和T中间的A的个数,而i呢是P前面A的个数~因为必须满足开头的A的个数*中间的A的个数 = 结尾的A的个数。所以检验的代码为(len – 1 – k) == ((k – 1 – i) * i);

记得要判断一下字符串中出现的每个字母,如果出现了PAT之外的字母,说明不符合题意;如果整个字符串都没有出现P或者A或者T,说明也是不符合题意的~(我的代码中是增加一个book标记三个字母是否出现过~如果有一个字母没出现过,就要return false)

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
bool judge(string str) {
	int len = str.length();
	if (len <= 2)
		return false;
	bool book[3] = { false };
	for (int i = 0; i < len; i++) {
		if (str[i] == 'P')
			book[0] = true;
		else if (str[i] == 'A')
			book[1] = true;
		else if (str[i] == 'T')
			book[2] = true;
		else
			return false;
		if (str[i] == 'P') {
			for (int j = 0; j < i; j++) {
				if (str[j] != 'A')
					return false;
			}
			if (str[i + 1] != 'A')
				return false;
			for (int k = i + 2; k < len; k++) {
				if (str[k] != 'A') {
					if (str[k] != 'T') {
						return false;
					}
					if ((len - 1 - k) != ((k - 1 - i) * i))
						return false;
					for (int m = k + 1; m < len; m++) {
						if (str[m] != 'A')
							return false;
					}
				}
			}
		}
	}
	if (book[0] == false || book[1] == false || book[2] == false)
		return false;
	return true;
}

int main() {
	int n;
	cin >> n;
	string s;
	for (int i = 0; i < n; i++) {
		cin >> s;
		if (judge(s) == true)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值