1003 我要通过! (20分)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符;- 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串;- 如果
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
解题思路:
- 第一条规则规定了输入的字符串中只能含有P、A、T三种字符。
- 第二条规则需要与第三条规则结合起来看。
- 第三条规则最有意思,当打上眼看的时候,一脸懵逼,直到在网上看了一些大佬的解释,才慢慢开始理解,正如上面所说的,第三条规则与第二条规则需要结合起来看,如果aPbTc是正确的能推导出什么结论呢?看第二条规则,形如xPATx均正确,其中x为空串或者仅由A组成的字符串。如果aPbTc是正确的,由第二条规则可知,b = A,a = c,再往下看,那么aPbATca也是正确的,仔细观察,PT之间多了一个a,相应的T右边多了一个a,也就是说aPT之间每有一个A,那么T右边就相应的多一个a,如此看来,xPATx就可以看做是中间有一个A的情况,即xPATx --> aPATa,所以,综合起来看,由于规则1限制了字符的种类,所以T右边A的个数就等于P左边A的个数乘以PT中间A的个数,此时字符串正确,反之错误。
- 总之一句话,P前面A的个数 * PT之间A的个数 = T后面A的个数且PT之间至少有一个A,最后切记!!!P要在T的前面,这一点困扰了我很长时间,直到看见了一个兄弟博客才恍然大悟 答案正确 。
代码实现:
/* 答案正确的条件
* 1.仅含P、A、T三种字符
* 2.P、T之间至少有一个A且P、T顺序固定
* 3.(P左侧A的数量) * (PT之间A的数量) = (T右侧A的数量)
*/
#include <stdio.h>
int main()
{
int n = 0;
int answer[10] = { -1 }; //字符串的判决结果,10是因为n < 10,0:NO,1:YES,-1:初始状态
int index = 0; //index = 0,累加的P左边A的个数,index = 1,累加的是PT中间A的个数,index = 2,累加的是T右边A的个数
int count1 = 0; //P左边即a中A的个数
int count2 = 0; //PT中间A得个数
int count3 = 0;
int j = 0;
char str[101];
scanf("%d", &n);
getchar(); //吃掉回车
for(int i = 0; i < n; i++)
{
gets(str);
while(1)
{
if(str[j] == 'P' || str[j] == 'A' || str[j] == 'T')//正常情况下仅有P、A、T
{
if((str[j] == 'P' && index == 0) || (str[j] == 'T' && index == 1))//正常情况下index = 2,若index != 2,错误,切记要保证P在T的前面
{
index++;
}
else//累加A的个数
{
switch(index)
{
case 0: count1++; break;
case 1: count2++; break;
case 2: count3++; break;
default: break;
}
}
}
else
{
if(str[j] == '\0')//回车符
{
if(count3 == (count1 * count2) && index == 2 && count2 >= 1)//注意PT之间至少有一个A
answer[i] = 1;
else
answer[i] = 0;
}
else//其他字符直接判NO
{
answer[i] = 0;
}
break;
}
j++;
}
count1 = count2 = count3 = index = j = 0;//莫要忘记变量归零
}
for(int i = 0; i < n; i++)
{
switch(answer[i])
{
case 1: printf("YES\n"); break;
default: printf("NO\n"); break;
}
}
return 0;
}
来源:CSDN
作者:阿涛爱上了阿澄
链接:https://blog.csdn.net/W_Beloved/article/details/104024563