PAT 1003 我要通过!

题目

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

  1. 字符串中必须仅有 PAT这三种字符,不可以包含其它字符;
  2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x或者是空字符串,或者是仅由字母 A 组成的字符串;
  3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 abc均或者是空字符串,或者是仅由字母 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

思路1

好久没做这么费体力的题了,清明假期浪了几天,有点,emmmm,算是做了好几天的题吧,现在答案部分正确。
题目给了三个条件,前两个很简单,条件一

  1. 字符串中必须仅有 PAT这三种字符,不可以包含其它字符;

是必要条件,条件二

任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;

是解题关键,从条件三

如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 abc均或者是空字符串,或者是仅由字母
A 组成的字符串。

可以看出,答案要么满足条件二,要么可以转换为条件二,也就是xPATx
思路如下:
1、拿到字符串,先判断是否符合条件一,再看是否符合条件二,而且隐藏条件就是PT都有且只有出现一次,答案一中未体现,导致出现2错误,修正部分在答案2,修正后4正确2超时。如果符合条件二则输出YES,否则执行下一步。
2、如果给的是aPbATca形,则去掉它中间的A和后面的a,转换成aPbTc 形,迭代至b只有一个A时,判断是否符合xPATx形,并输出结果。
其中由于abc只含有A,P和T只出现一次,所以可以从aPbATca形中解析出a,再分解出 cb就很简单了,PT中间除掉一个A就是b了。

思路2

这个思路来自百度,果然dalao多,直接看呆了我。

  1. 首先,不管什么形,看成aPbTc,不符合这个形直接out。
  2. 然后,a只能由A组成,A的个数可以是任意大于等于0的整数。记A的个数n1b只能由A组成,个数可以是任意大于等于1的整数。记个数n2c只能由A组成,个数可以是任意大于等于0的整数。记个数n3
  3. 到这里没问题的话,直接验证, n 1 × n 2 = = n 3 n1\times n2==n3 n1×n2==n3 等式成立则YES,否则NO

这个等式的来源是这样的。假如给的是可以YES的字符串aPbATca,可以通过去掉它中间的A和后面的a,转换成aPbTc 形,通过迭代总是可以变成xPATx形,此时n1n2n3的关系成立。将xPATx往原式逆推一次则为xPAATxx,两次为xPAAATxxx,中间A的数量总会等于T后x的数量。从而可以得到 n 1 × n 2 = n 3 n1\times n2=n3 n1×n2=n3
对应答案4,代码量少了一大半,niubility。

答案1(2正确,2错误,2超时。2020-4-7 21:52:33)

#include <stdio.h>
int isOnlyPAT(char str[])
{
	int i = 0;
	while(str[i]!='\0')
	{
		if(str[i]!='P'&&str[i]!='T'&&str[i]!='A')
			return 0;
		i++;
	}
	return 1;
}

int isxPATxform(char str[])
{
	int i = 0;//point at front
	int j = 0;//point at tail
	while(str[j]!='\0')
	{
		j++;
	}
	j--;

	while(str[i++]==str[j--]);
	i--;
	j++;

	//printf("%d%d",i,j);
	if(str[i]=='P'&&str[i+1]=='A'&&str[i+2]=='T'&&i+2==j)
	{
		return 1;
	}else
	{
		return 0;
	}

}

int isOkToChangeaPbTcPass(char str[])
{
	/*

	if aPbTc ok,then aPbATca OK
	and original aPbTc shoulb be xPATx form
	
	1.from aPbATca we can prase out a,b and c
	2.and then recombination to aPbTc,
	3.if the aPbTc isn't the xPATx form then repeat above steps
	4.if fail to repeat then return false 
	*/

	char a[100];
	char c[100];
	char newstr[100];

	if(isxPATxform(str))
	{
		return 1;
	}
	
	//prase a
	int i=0;
	while(str[i]=='A')
	{
		a[i] = str[i];
		i++;
	}
	a[i] = '\0';
	
	if(str[i] != 'P')
	{
		return 0;
	}
	i--;

	//printf("sdf");
	//prase c and confime the aPbATca form
	int j = 0;
	while(str[j]!='\0')
	{
		j++;
	}
	j--;//j point at tail

	while(i>=0)
	{
		if(a[i]==str[j])
		{
			i--;
			j--;
		}
	}
	//j point at c tail

	int k = 0;
	while(str[k]!='T')
	{
		k++;
	}
	k++;
	//k point at c front
	
	i=0;
	for(k;k<=j;k++)
	{
		c[i++] = str[k]; 
	}
	c[i] = '\0';
	//phrase c done
	
	//constract newstr
	i = 0;
	while(a[i]!='\0')
	{
		newstr[i] = a[i];
		i++;
	}

	newstr[i] = 'P';
	i++;
	while(str[i] != 'T')
	{
		newstr[i]=str[i];
		i++;
	}
	i--;
	newstr[i] = 'T';
	i++;

	j = 0;
	while(c[j]!='\0')
	{
		newstr[i] = c[j];
		i++;
		j++;
	}
	newstr[i] = '\0';
	
	if(isxPATxform(newstr)==1)
		return 1;
	else
		return isOkToChangeaPbTcPass(newstr);
}

int main(int argc, char* argv[])
{
	char string[101] = {"AAPAAATAAAAAA"};
	int n;
	int i = 0;

	scanf("%d",&n);
	
	for(i = 0; i < n ;i++)
	{
		scanf("%s",&string);
		if(isOnlyPAT(string)==1&&isOkToChangeaPbTcPass(string)==1)
		{
			printf("YES\n");
		}else
		{
			printf("NO\n");
		}	
	}
	//printf(isOkToChangeaPbTcPass(string)?"true\n":"false\n");
	return 0;
}

答案2(4正确2超时,2020-4-7 22:34:55)

// only revise this function
int isOnlyPAT(char str[])
{
	int i = 0;
	while(str[i]!='\0')
	{
		if(str[i]!='P'&&str[i]!='T'&&str[i]!='A')
			return 0;
		i++;
	}
	
//add this part
	int countT = 0;
	int countP = 0;
	 i = 0;
	while(str[i]!='\0')
	{
		if(str[i]=='P')
			countP++;
		
		if(str[i]=='T')
			countT++;

		i++;
	}
	if(countT == 1 && countP == 1)
		return 1;
	else return 0;
	//add end
}

答案3(全正确,2020-4-7 23:08:05)

将记录ac的字符串修改成记录只记录ac的长度,就不超时了。

#include <stdio.h>
int isOnlyPAT(char str[])
{
	int i = 0;
	while(str[i]!='\0')
	{
		if(str[i]!='P'&&str[i]!='T'&&str[i]!='A')
			return 0;
		i++;
	}
	int countT = 0;
	int countP = 0;
	 i = 0;
	while(str[i]!='\0')
	{
		if(str[i]=='P')
			countP++;
		
		if(str[i]=='T')
			countT++;

		i++;
	}
	if(countT == 1 && countP == 1)
		return 1;
	else return 0;
}

int isxPATxform(char str[])
{
	int i = 0;//point at front
	int j = 0;//point at tail
	while(str[j]!='\0')
	{
		j++;
	}
	j--;

	while(str[i++]==str[j--]);
	i--;
	j++;

	if(str[i]=='P'&&str[i+1]=='A'&&str[i+2]=='T'&&i+2==j)
	{
		return 1;
	}else
	{
		return 0;
	}

}

int isOkToChangeaPbTcPass(char str[])
{
	/*

	if aPbTc ok,then aPbATca OK
	and original aPbTc shoulb be xPATx form
	
	1.from aPbATca we can prase out a,b and c
	2.and then recombination to aPbTc,
	3.if the aPbTc isn't the xPATx form then repeat above steps
	4.if fail to repeat then return false 
	*/
	
	int n = 0 ; //longth of str
	int counta=0;//a and c is only a string consist of a serise of 'A'
	int countc=0;//we only need to count the number of it 
	char newstr[100];
	if(isxPATxform(str))
	{
		return 1;
	}
	
	//count A number
	int i=0;
	while(str[i++]=='A');
	i--;
	counta = i;// number =  index +1 
	if(str[i] != 'P')
	{
		return 0;
	}
	
	//count C number
	int j = 0;
	while(str[n]!='\0')
	{
		if(str[n] == 'T')
		j = n;
		n++;
	}

	countc = n - j - counta -1;
	
	//printf("%d,%d\n",counta,countc);
	//constract newstr
	
	for(i = 0 ;i < counta; i++)
	{
		newstr[i] = 'A';
	}
	newstr[i++] = 'P';
	
	while(str[i] != 'T')
	{
		newstr[i]=str[i];
		i++;
	}
	i--;
	newstr[i] = 'T';
	i++;
	
	for(j = 0;j < countc; j++)
	{
		newstr[i++] = 'A';
		
	}
	newstr[i] = '\0';
	//printf("%s\n",newstr);
	if(isxPATxform(newstr)==1)
		return 1;
	else
		return isOkToChangeaPbTcPass(newstr);
}

int main(int argc, char* argv[])
{
	char string[101] = {"AAPAAATAAAAAA"};
	int n;
	int i = 0;

	scanf("%d",&n);
	
	for(i = 0; i < n ;i++)
	{
		scanf("%s",&string);
		if(isOnlyPAT(string)==1&&isOkToChangeaPbTcPass(string)==1)
		{
			printf("YES\n");
		}else
		{
			printf("NO\n");
		}	
	}
	return 0;
}

答案4(2020-4-8 01:38:24)

#include <stdio.h>
int isOnlyPATLetter(char str[])
{
	//and both P and T numbers only one
	// and position of P before T, at least one A betweem

	int i = 0;
	while(str[i]!='\0')
	{
		if(str[i]!='P'&&str[i]!='T'&&str[i]!='A')
			return 0;
		i++;
	}

	//count T,count P
	int countT = 0;
	int countP = 0;
	//position T and position P
	int positionT = 0;
	int positionP = 0;
	i = 0;
	while(str[i]!='\0')
	{
		if(str[i]=='P')
		{
			countP++;
			positionP = i;
		}
		if(str[i]=='T')
		{
			countT++;
			positionT = i;
		}
		i++;
	}

	if(countT == 1 && countP == 1 && (positionT - positionP > 1))
		return 1;
	else return 0;
}

int isN1TimesN2EqualN3(char str[])
{
	/*
	the form of str is aPbTc
	define numbers of A in position of a N1
	define numbers of A in position of b N2
	define numbers of A in position of c N3
	if N1 * N2 == N3 then return 1,else return 0
	*/
	
	int n1 = 0 ; 
	int n2 = 0 ; 
	int n3 = 0 ; 
	int i = 0 ;
	while(str[i++]=='A');
	n1 = i - 1;
	while(str[i++]=='A');
	n2 = i - 2 - n1;
	while(str[i++]!='\0');
	i--;
	n3 = i - 2 - n1 - n2;

	if(n1 * n2 == n3)
		return 1;
	else
		return 0;
}

int main(int argc, char* argv[])
{
	char string[101] = {'\0'};
	int n;
	int i = 0;

	scanf("%d",&n);
	
	for(i = 0; i < n ;i++)
	{
		scanf("%s",&string);
		if(isOnlyPATLetter(string)==1&&isN1TimesN2EqualN3(string)==1)
		{
			printf("YES\n");
		}else
		{
			printf("NO\n");
		}	
	}
	return 0;
}

总结

c语言没有bool类型,差点雷倒我。程序写的很慢,倒没什么卡壳调bug的地方。还是字符串,很繁复,需要慢慢理,我连把i++写在变量里边都怂。。。
搞定,等下去百度看看其他dalao的答案,很期待有人可以来一起交流一下,两个人讨论比一个人刷题有意思。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值