题目
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
思路
一开始拿到这条题目,说实话,我是有点懵的。准确来说,不知道是题目表述问题还是我自身理解能力存在问题,我读了n遍题目都没读懂。在5天之后,我重拾这条题目,在百度了各位大神的思路后,完成了该题。
“答案正确”的字符串必须满足以下规则:
1、只存在P、T、A三种字符
2、以P、T字符作为分界点(P字符必须在A字符之前),将字符串分为3部分来看。记字符P所在索引为pIndex,字符T所在索引为tIndex。索引0 ~ pIndex - 1之间的字符必须均为A,个数记为n1,;索引pIndex + 1 ~ tIndex ~ 1之间的字符也必须均为A,个数记为n2;索引tIndex + 1 ~ length - 1(length为字符串长度)之间的字符也必须均为A,个数记为n3。其中,n1 >= 0,n2 >= 1,n3 >= 0 && n3 = n1 * n2。
满足以上条件的字符串,必定获得“答案正确”。
代码
所有的代码均是原创,自行编写且通过PTA系统测试的,欢迎大家提建议!!!
#include <stdio.h>
#include <string.h>
#define MAXSIZE 100
void init(char (*p)[MAXSIZE],int n);
void printStr(char (*p)[MAXSIZE],int n);
void check(char (*p)[MAXSIZE],int n,int *flag);
int isAllA(char *p,int start,int end);
void output(int *flag,int n);
int main(){
int n;
scanf("%d",&n);
getchar();
char str[n][MAXSIZE];
init(str,n); //初始化n个字符串
//printStr(str,n); //输出n个字符串
int flag[n];
check(str,n,flag);
output(flag,n);
return 0;
}
void init(char (*p)[MAXSIZE],int n){ //初始化n个字符串
for(int i = 0;i < n;i++){
gets(*(p + i));
}
}
void printStr(char (*p)[MAXSIZE],int n){ //输出n个字符串
for(int i = 0;i < n;i++){
printf("%s\n",*(p + i));
}
}
void check(char (*p)[MAXSIZE],int n,int *flag){
for(int i = 0;i < n;i++){ //初始化flag数组
*(flag + i) = 1;
}
for(int i = 0;i < n;i++){
int length = strlen(*(p + i));
int pIndex = -1,tIndex = -1;
int j = 0;
while(*(*(p + i) + j) != 0){ //寻找第一个p字符
if(*(*(p + i) + j) == 'P'){
pIndex = j;
break;
}
j++;
}
int k = j + 1;
while(*(*(p + i) + k) != 0){ //寻找第一个t字符
if(*(*(p + i) + k) == 'T'){
tIndex = k;
break;
}
k++;
}
if(pIndex != -1 && tIndex != -1){ //pIndex、tIndex不等于-1,说明存在p、t字符
int n1 = pIndex,n2 = tIndex - pIndex - 1,n3 = length - 1 - tIndex;
if(n2 >= 1 && (n1 * n2) == n3){ //假设P、A之间均为A,判断是否满足数量关系。满足则验证是否全为A
int f1 = isAllA(*(p + i),0,pIndex - 1),f2 = isAllA(*(p + i),pIndex + 1,tIndex - 1),f3 = isAllA(*(p + i),tIndex + 1,length - 1);
if(f1 == 0 || f2 == 0 || f3 == 0){
*(flag + i) = 0;
}
}else{
*(flag + i) = 0;
}
}else{
*(flag + i) = 0;
}
}
}
int isAllA(char *p,int start,int end){ //检查指定范围内的字符是否均为A
int flag = 1;
for(int i = start;i <= end;i++){
if(*(p + i) != 'A'){
flag = 0;
break;
}
}
return flag;
}
//第一次提交失败,应该是大写的YES/NO
void output(int *flag,int n){ //输出yes或no
for(int i = 0;i < n;i++){
if(i != n - 1){
if(*(flag + i)){
printf("YES\n");
}else{
printf("NO\n");
}
}else{
if(*(flag + i)){
printf("YES");
}else{
printf("NO");
}
}
}
}