PAT刷题之乙级1003(cpp)
题目描述
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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
问题分析
我们来看三个条件,由条件(1)可以知道若出现了P、A、T之外的其他字符,则判错。由条件(2)可知,一个字符串中出现了‘PAT’,就可以判对。好了,最重要的条件(3)来了。
条件(3)里给出了两个条件:一个是归纳结论,一个是a、b、c要是为空,全
为空;要是为A,全
为由A组成的字符串。
那么来看第一个归纳结论。现在我们假设a、b、c为空,那么可得
a | b | c | |
---|---|---|---|
aPbTc | 空 | 空 | 空 |
aPbATca | 空 | 空 | 空 |
即为 PT–>PAT
再假设a、b、c为A,那么可得
aPbTc | a | b | c |
---|---|---|---|
初始 | A | A | A |
一次变化( aPbATca) | A | AA | AA |
二次变化( aPbAATcaa) | A | AAA | AAA |
… | A | … | … |
n次变化 | A | n+1个A | n+1个A |
再假设a=AA、b=A、c=AA,那么可得
aPbTc | a | b | c |
---|---|---|---|
初始 | AA | A | AA |
一次变化( aPbATca) | AA | AA | AAAA |
二次变化( aPbAATcaa) | AA | AAA | AAAAAA |
… | AA | … | … |
n次变化 | AA | n+1个A | 2*(n+1)个A |
故我们可以得到推理表达式:a*b=c
另外,当a=b=c=A…AAA(A的个数大于1)或者其他不合符该推理表达式的a、b、c的取值时,并不包括在符合条件(2)的字符串中,也即aPbTc本身就是错误的,aPbATca要想是对的,首先aPbTc先是符合条件的字符串。所以条件(2)是在为条件(3)做铺垫。
程序设计
在设计程序时,对于以下几种情况要将其判错:
一、出现多个P、T;
二、P、T调换位置;
三、出现其他字符;
四、不符合推理表达式;
五、前面几种情况的结合。
代码实现
核心代码如下:
bool panduan(string str) {
int count_a = 0, count_b = 0, count_c = 0,P=0,T=0;
char t = ' ';
for (int i = 0; i < str.length(); i++) {
if (str[i] == 'P' || str[i] == 'T'){
t = str[i];
if (t == 'P')
if(T > 0 || P > 0) //出现多个P或者T判错,否则个数加一
return false;
else
P++;
else if (t == 'T')
if( T > 0 || P == 0) //T在P前面出现判错,否则个数加一
return false;
else
T++;
}
if (str[i] != 'P' && str[i] != 'A' && str[i] != 'T') // 出现其他字符判错
return false;
if (str[i] == 'P' && str[i + 1] == 'A' && str[i + 2] == 'T') //符合条件二的字符串直接判对
return true;
if (str[i] == 'A') { //计算a,b,c中A的个数
if (t !='P'&& t!='T')
count_a++;
else if (t == 'P')
count_b++;
else
count_c++;
}
}
if (count_b < 1)
return false;
else if (count_a * count_b == count_c && P==1 && T==1) //符合推理条件三并且P、T只有一个
return true;
else return false; //否则判错
}
完整代码实现如下:
代码在这里鸭~