1003. 我要通过!(20)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
输入样例:8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
解题思路:这道题的题目似乎很难读懂,在借助其他同行的点拨之后,稍微有点思路。按照1,2,3一步步走,逐一写出符合条件的字符串,然后找出规律,用代码实现它。。具体是这样实现的:
1、只包含 P,A,T三种字符,并且三个字符一定存在;
2、APATA、AAPATAA、AAAPATAAA都是正确的,所以两边的话,可以加上相同个数的A;
3、在2的基础上,可以推导出若干正确的答案。PAAT,PAAAT,PAAAAT……;APAATAA,APAAATAAA,AAPAATAAAA,AAAPAATAAAAAA……
由此,我们可以得出:
只包含一个P以及一个T,A的数量>=1待定;
而且P、T的位置是固定的,根据判断可以直接返回False;
在P左侧,T的右侧以及PT的中间加上若干的A,使A的数量上满足一定规律:暂且标记为 a1 P a2 T a3,
有:a1 * a2 = a3
怎么用代码实现它呢???
版本1、C++
#include <iostream>
#include <string>
using namespace std;
bool passOK(string str) {
int len = str.length();
int na[3] = {0}; //定义一个存放A数量的数组
int idx = 0, //索引参数
np = 0, //P的数量
nt = 0; //T的数量
if (len <= 2) { //直接返回
return false;
}
for (int i = 0; i < len; i++) { //遍历整个数组,对P,A,T的各个数量进行统计,放入数组里;
if (str[i] == 'A') { //判断特定情况下的return false
na[idx] += 1;
}
else if (str[i] == 'P') {
if (np > 0) return false;
np += 1;
idx += 1;
}
else if (str[i] == 'T') {
if (np == 0 || nt > 0) return false;
nt += 1;
idx += 1;
}
else return false;
}
if (na[0] * na[1] == na[2] && na[1] > 0) { //主要判断条件
return true;
}
return false;
}
int main() {
int n;
string s;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> s;
if (passOK(s) == true)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
//system("pause");
return 0;
}
版本2、Python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/6 13:57
# @Author : WuFan
def passOK(string):
na = [0, 0, 0] # 定义a1,a2,a3分别代表A的数量
idx, np, nt = 0, 0, 0 # 定义P和T的数量参数,还有idx参数代表位置(P前,PT中,还是T后,很关键)
if len(string) <= 2: # 直接返回
return False
for i in string:
if i == 'A':
na[idx] += 1
elif i == 'P':
if np > 0:
return False
np += 1
idx += 1
elif i == 'T':
if np == 0 or nt > 0:
return False
nt += 1
idx += 1
else:
return False
if na[0] * na[1] == na[2] and na[1] > 0:
return True
return False
if __name__ == "__main__":
n = int(input())
for i in range(n):
string = input().strip() # 对于这个地方的str.strip(),是默认删除空白符(包括'\n', '\r', '\t', ' '),不加在官方OJ可以通过,但在牛客过不了;加了均可以通过
if passOK(string):
print('YES')
else:
print('NO')
idx的设置是以后可以学习的地方,很巧妙;
str.strip() 的功能后面也可以用到,还记得它的用法吗?
声明:s为字符串,rm为要删除的字符序列
s.strip(rm) 删除s字符串中开头、结尾处,位于 rm删除序列的字符
s.lstrip(rm) 删除s字符串中开头处,位于 rm删除序列的字符
s.rstrip(rm) 删除s字符串中结尾处,位于 rm删除序列的字符
1. 当rm为空时,默认删除空白符(包括'\n', '\r', '\t', ' ')
2.这里的rm删除序列是只要边(开头或结尾)上的字符在删除序列内,就删除掉。
>>> a = ' 123'
>>> a.strip()
'123'
>>> a='\t\tabc'
'abc'
>>> a = 'sdff\r\n'
>>> a.strip()
'sdff'
2.这里的rm删除序列是只要边(开头或结尾)上的字符在删除序列内,就删除掉。
>>> a = '123abc'
>>> a.strip('21')
'3abc' 结果是一样的
>>> a.strip('12')
'3abc'