PAT乙级:1003 我要通过! C/C++实现

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

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

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 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

题目分析

这道题需要按题目要求一个个分析(感觉考虑的有点麻烦,可以直接看结论):
1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
即出现P、A、T以外的字符均不正确
2.任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
若字符串正确,则P,T只能出现一次,P后必跟着A
x=x,即若PAT左侧的x由n个A组成,那么PAT右侧的x也一定是由n个A组成
3.如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
P、T间可以是由数个A组成的字符串,但是必须至少有一个A

结合2,3条(假设此时字符串已是A…PA…TA…的形式):

  • 可以设立三个整型变量,分别记录P前A的数量a’,P、T之间的A的数量b’,T后A的数量c’;
  • 若想aPbTc是正确的,首先b必须是至少由一个A组成的字符串,即b’≥1。当b’=1时,a’=c’;
  • 假设有两个字符串M和N,M的a’=a1,b’=b1,c’=c1,N的a’=a2,b’=b2,c’=c2,M符合aPbTc形式,且a1=a2,b2=b1+1,c2=a1+c1,则N也正确

可以进行一下简单的推算:

由最简单的形式开始:aPATc,此时b’=1,a’=c’;(初始的a’,b’,c’,后用(初)a’的形式指代这里的a’,b’,c’)
若aPATc正确,则aPAATca正确,新的字符串a’=(初)a’,b’=2,c’=(初)c’+(初)a’=2(初)a’
此时aPAATca正确,则aPAAATcaa也正确,新的字符串a’=(初)a’,b’=3,c’=(上一个字符串的)c’+(初)a’=2(初)+a’(初)a’=3(初)a’
可以经行多次想上次的推算
由此可以推出结论:
只要a’*b’=c’且b’>0即可 满足2、3条件(a’、b’、c’均指现在的字符串的a’、b’、c’a)

根据这几条限定要求,我完成了下面的代码,给大家做个参考:

#include<iostream>
#include<map>
using namespace std;
bool fun(string s,int len)//判断字符串是否有P、A、T以外的字符
{
	for(int i=0;i<len;i++)
	{
		if(s[i]!='P'&&s[i]!='A'&&s[i]!='T')
		return 0;//字符串中出现了非P、A、T的字符 
	}
	return 1;//字符串完全由P、A、T构成 
}
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		string s;
		map<char,int> m;//记录每个字符出现的次数 
		int a,b,c,len;//a=P前A的数量,b=PT间A的数量,c=T后A的数量 
		cin>>s;
		len=s.length();
		if(!fun(s,len))//字符串中出现了非P、A、T的字符
		{cout<<"NO"<<endl;
		continue;}
		for(int i=0;i<len;i++)
		{
			m[s[i]]++;//s[i]的字符的数量+1 
			if(s[i]=='P')//由条件2可得,字符串中只能出现一个P,即P出现了就可以求得a的值 
			a=i;//a的值同样代表了P出现的数组标号 
			if(s[i]=='T')//由条件2可得,字符串中只能出现一个T,即T出现了就可以求得b,c的值
			{
				b=i-a-1;//i此时等于T出现的数组编号,a等于P出现的数组编号
				c=len-i-1; 
			} 
		}
		if(m['P']!=1||m['T']!=1)//P、T出现的次数不为1 
		{cout<<"NO"<<endl;
		continue;}
		if(c==a*b&&b>0)
		cout<<"YES"<<endl;
		else
		{cout<<"NO"<<endl;
		continue;}
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值