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的整数


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