PAT 乙级 1003 我要通过

题目

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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三个字母组成。所以判断字符串里有其他字符出现就答案错误。
2、“PAT”的左右为空或者左右的“A”的数量相同,则答案正确。
3、第三个条件是以第二个条件为基础的。把条件二代入条件三,即“若xPATx”正确,则“xPAATxx”正确,即“xPAAATxxx”正确,即“xPAAAATxxxx”正确……可以得出规律:“P”前面的“A”的数量与“P”“T”之间的“A”的数量相乘等于“T”后面的“A”的数量。

所以我将“P”前面“A”的数量累加到a,“P”“T”之间“A”的数量累加到b,“T”后面的“A”的数量累加到c。
然后判断a*b=c时答案正确。

根据三个条件还能得出几个没有明确指出的隐藏条件:
“P”、“T”必须出现,且只能出现一次,出现的顺序一定是“P”在“T”的前面。
“P”、“T”中间一定要出现过“A”,即,b>0。

我第一次提交时测试点1一直没通过,想了很久才发现忘记判断T是否存在了,导致输入AP会输出YES。

AC代码

#include<iostream>
#include"stdio.h"
#include"math.h"
#include"string.h"
using namespace std;

int main(){
	int a,b,c;
	int i,j,l;
	char s[110];
	int k,n,m,r;
	while(cin>>k){
		getchar();
		for(j=0;j<k;j++){
			cin>>s;
			l=strlen(s);
			a=0;b=0;c=0;
			n=0;m=0;r=0;
			for(i=0;i<l;i++){
				if(s[i]!='A'&&s[i]!='P'&&s[i]!='T'){
					r=1;break;
				}else if(s[i]=='A'){
					if(n==0)  a++;
					else if(n==1&&m==0)  b++;
					else if(n==1&&m==1)  c++;
				}else if(s[i]=='P'){
					if(n==0)  n=1;
					else{
						r=1;break;
					}
				}else if(s[i]=='T'){
					if(n==0){
						r=1;break;
					}else if(n==1&&m==0)  m=1;
					else if(n==1&&m==1){
						r=1;break;
					}
				}
			}
			if(n!=1||m!=1)  r=1;
			if(b==0)  r=1;
			
			if(r==1) cout<<"NO"<<endl;
			else if(b!=0&&a*b==c)  cout<<"YES"<<endl;
			else  cout<<"NO"<<endl;			
		}
	}
	return 0;
}

思路优化

我的a、b、c是遍历字符串数组然后累加进去的。
看到很多大佬都是直接记录字符串数组里P、T的位置,代码要简洁的多。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值