PAT (Basic Level) Practice 1003

本文介绍了一种自动裁判程序的设计,用于判断字符串是否符合特定的PAT规则,即字符串仅包含P、A、T字符,并遵循特定的组合模式。文章详细解析了评判标准和实现思路,分享了原创代码并通过了PTA系统测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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");
			}	
		} 
			
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值