1003 我要通过
“答案正确” 是自动判题系统给出的最令人喜欢的回复。本题属于PAT的 “答案正确” 大派送——只要读入的字符串满足下列条件,系统就能输出 “答案正确” ,否则输出 “答案错误” 。
得到 “答案正确” 的条件是:
- 字符串中必须含有
p
、A
、T
这三种字符,不可以包含其他字符; - 任意形如
xPATx
的字符串都可以获得 “答案正确”, 其中x
或者是空字符串,或者是仅由A
组成的字符串; - 如果
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
解答
#include<stdio.h>
#include<string.h>
#define true 1
#define false 0
//判定字符串是否是全空或者全A
_Bool AllAPanding(char* s) {
if (strlen(s)==0)
return true;
for (int i = 0; i < strlen(s); i++) {
if (s[i] != 'A')
return false;
}
return true;
}
_Bool Panding(char* s, int n) {
int i, j = 0, k = 0;
char s_prefix[100], s_infix[100], s_suffix[100];
//获取P和T的位置
for (i = 0; i <= n; i++) {
if (s[i] != 'P' && i == j) {
j++;
}
if (s[i] == 'P') {
continue;
}
if (s[i] == 'T')
break;
}
k = i;
int l = 0;
//获取前缀、中缀、后缀
for (i = 0; i < j; i++) {
s_prefix[i] = s[i];
}
s_prefix[i] = '\0';
for (i = j + 1, l = 0; i < k; i++, l++) {
s_infix[l] = s[i];
}
s_infix[l] = '\0';
for (i = k + 1, l = 0; i < n; i++, l++) {
s_suffix[l] = s[i];
}
s_suffix[l] = '\0';
if (AllAPanding(s_infix) && AllAPanding(s_prefix) && AllAPanding(s_suffix)) {
if (strlen(s_prefix) == strlen(s_suffix) && strlen(s_infix) == 1)
//当且仅当前缀与后缀相同,且中缀为‘A'时正确
return true;
if (strlen(s_suffix) < strlen(s_prefix))
return false;
else {
//无法判定情况下,进行递归分解。后缀减去前缀,中缀减去一个‘A’
s_suffix[strlen(s_suffix) - strlen(s_prefix)] = '\0';
}
if (strlen(s_infix) == 0)
return false;
s_infix[strlen(s_infix) - 1] = '\0';
char s2[100];
s2[0] = '\0';
//重组字符串并进行递归
strcat_s(s2, 100, s_prefix);
strcat_s(s2, 100, "P");
strcat_s(s2, 100, s_infix);
strcat_s(s2, 100, "T");
strcat_s(s2, 100, s_suffix);
return Panding(s2, strlen(s2));
}
else {
//非全A/全空则返回false
return false;
}
}
int main(void) {
char s[105];
int n;
scanf_s("%d", &n);
for (int i = 1; i <= n; i++) {
scanf_s("%s", s, 105);
if (Panding(s, strlen(s))) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
思路
显然本题具有良好的递归性质,根据条件三可以知道如果aPbATca
正确,则前提是aPbTc
。也就是说,可以通过不断分解前缀、中缀、后缀,获得形如条件二的xPATx
从而求解。分解的条件即,后缀去掉一个字串a
,中缀去掉一个字符A
。
注:代码在浙大PTA系统中存在一个监测点未通过,但在牛客网中为通过。PTA由于检测数据未知,无法知道错误原因。欢迎知道错误原因的小伙伴留言!