“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符; - 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串; - 如果
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
解题思路:
读题之后,本人想到可以使用正则表达式的方式来判断输入串是否符合要求,但通过仔细阅读之后,发现单纯使用正则表达式是不够的(可能是本人没有发现,如果能直接判断求解,请各位大佬指导!),还需要再加上其他的判断。条件一只需使用一个for循环判断是否含有'P、'A'、'T'以外的字符即可;条件二除了使用正则表达式外,还需判断首尾的字符'A'数量是否相等,本人采取反转字符串后判断反转前'P'的位置和反转后'T'的位置是否相同间接判断;条件三的正则表达式本人一开始写的是"A*PA*TA*",通过测试和多次阅读题目后发现,'P'和'T'中间必须包含字符'A',故改正为"A*PAA*TA*",而由字符'P'和'T'划分出的三个区域中字符'A'的数量也包含着一定的数学关系,本人在阅读博客之后知晓,三者的关系如下:设'P'之前含a个字符'A','T'之后含c个字符'A',二者之间含b个字符'A',a*b=c,根据这个关系并结合字符串的长度和特殊字符的位置即可列出关系式。
正则表达式相关可参考该博客!
错误提示:
本人使用CodeBlocks进行代码的编写,在首次编译时CB产生如下报错:C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\c++0x_warning.h|32|error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.| \main.cpp||In function 'void judge(std::__cxx11::string)':|
这个报错中提到需要启用C++11标准支持,需要在CodeBlocks的编译选项中添加-std=c++11
或-std=gnu++11来解决。
具体解决方法如下:
- 打开你的CodeBlocks项目。
- 在菜单栏中选择 “项目(Project)”,然后选择 “构建选项(Build options)”。
- 在弹出的对话框中,选择 “Debug” 配置(或你目前正在使用的配置)。
- 在左侧窗格中,选择你的主项目(默认为"Default")。
- 在右侧窗格中,找到 “编译器设置(Compiler settings)” 选项卡。
- 在 “Compiler flags” 字段中添加
-std=c++11
或-std=gnu++11
。 - 单击 “确定” 保存更改。
代码:
#include <iostream>
#include <string>
#include <regex> // 引入操作正则表达式相关函数所需的头文件
using namespace std;
void judge(string s)
{
int i;
bool res, res2;
for(i=0; i<s.length(); i++) // 遍历字符串,查看是否含有P、A、T以外的字符
{
if(s[i]!='P'&&s[i]!='A'&&s[i]!='T')
{
cout << "NO" <<endl;
return ;
}
}
res = regex_match(s, regex("A*PATA*")); // 条件二初判
res2 = regex_match(s, regex("A*PAA*TA*")); // 条件三初判
if(res){ // 若输入串为条件二形式,判断首尾'A'的长度是否相等
string str = s;
reverse(s.begin(), s.end()); // 将字符串反转
if(s.find('P') == str.find('T')){ // 判断反转前'P'的位置和反转后'T'的位置是否相同即可知晓首尾'A'的长度是否相等
cout << "YES" << endl;
}
else{
cout << "NO" <<endl;
}
}
else if(res2){ // 若输入串为条件二形式,继续判断,根据题目要求,设'P'之前含a个字符'A','T'之后含c个字符'A',二者之间含b个字符'A',查找规律后发现,a*b=c,由此判断是否符合要求
int p, t, l;
p = s.find('P');
t = s.find('T');
l = s.length();
if(p*(t-p-1) == l-t-1){
cout << "YES" <<endl;
}
else{
cout << "NO" <<endl;
}
}
else{
cout << "NO" <<endl;
}
}
int main()
{
int n, i;
string s;
cin >> n;
for(i=0; i<n; i++)
{
cin >> s;
judge(s);
}
return 0;
}