1003 我要通過!



// “答案正確”是自動判題系統給出的最令人歡喜的回覆。本題屬於PAT的“答案正確”大派送 —— 只要讀入的字符串滿足下列條件,系統就輸出“答案正確”,否則輸出“答案錯誤”。
// 
// 得到“答案正確”的條件是:
// 
// 1. 字符串中必須僅有P, A, T這三種字符,不可以包含其它字符;
// 2. 任意形如 xPATx 的字符串都可以獲得“答案正確”,其中 x 或者是空字符串,或者是僅由字母 A 組成的字符串;
// 3. 如果 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

#include <stdio.h>
#include <string.h>

bool YESorNO(char str[]);

int main(void)
{
	int strnum;				// 用以存儲用戶將要輸入的字符串的數目
	char str[10][101];		// 用以存儲用戶輸入的strnum個字符串,據題意,串數不超過10個,每串內容不超過100個字符

	scanf("%d", &strnum);	// 注意處理掉用戶輸入數字後的換行符
	getchar();				// 更要注意,不要用scanf("%d\n", &num)這種方式處理行末的換行符,這表示用戶要在鍵盤上輸入一個“\n”,而不是回車

	for (int i = 0; i < strnum; i++)
		gets(str[i]);		// gets()函數會自動處理掉每行末尾的換行符

	for (int i = 0; i < strnum; i++)
	{
		if (YESorNO(str[i]))
			printf("YES\n");
		else
			printf("NO\n");
	}

	return 0;
}

// 用以判斷某個字符串是否符合題意
bool YESorNO(char str[])
{
	int numP = 0;
	int numA = 0;
	int numT = 0;
	int numPAT = 0;
	int posP = 0;
	int posT = 0;

	// 統計字符串中P/A/T各自的數目,及P與T的位置
	// 要注意,strlen()函數的返回值是unsigned int類型
	for (unsigned int i = 0; i < strlen(str); i++)
	{
		switch (str[i])
		{
		case 'P':
			posP = i;
			numP++;
			break;
		case 'A':
			numA++;
			break;
		case 'T':
			numT++;
			posT = i;
			break;
		default:
			break;
		}
	}
	numPAT = numP + numA + numT;

	if (
		numPAT != strlen(str)	// 這說明字符串中還有其它字符,
		|| posT - posP <= 1		// 這說明P與T之間要麼沒有A,要麼T在P前面
		|| numP > 1				// 這說明串中有多個P
		|| numT > 1				// 這說明串中有多個T
		|| posP * (posT - posP - 1) != strlen(str) - posT - 1
		// posP即爲P之前A的數目
		// posT-posP-1即爲P與T之間A的數目減1,即P與T之間多餘的A的數目
		// strlen(str)-posT-1即爲T之後A的數目
		)
		return false;
	else
		return true;
}
// 該題的難點在於瞭解題意
// 結合第二第三個條件,可知:
// 1:字符串中必須有,也只能僅有P/A/T三種字符
// 2:"(n個A)PAT(n個A)"是合法的
// 3:在上一條的基礎上,P與T之間每增加一個A,其末尾就應當增加n個A,即(n個A)P(m個A)T(n*m個A)是合法的
//    即上一條是m==1的特殊情況
// 所以可得合法字符串的通項公式"(n個A)P(m個A)T(n*m個A)",其中n是大於0的整數,m是大於1的整數


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章