1. 程式人生 > >PAT (Basic Level) Practice 1003

PAT (Basic Level) Practice 1003

題目

“答案正確”是自動判題系統給出的最令人歡喜的回覆。本題屬於 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。

滿足以上條件的字串,必定獲得“答案正確”。

程式碼

#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");
			}	
		} 
			
	}
}