PAT乙级1003题目详细解析

首先祝各位小伙伴们元宵节快乐图片图片图片

接下来来看今天的题目,稍微有些难理解,各位如果一直弄不明白小伙伴要仔细看我的讲解了,希望我可以帮到你。

1003 我要通过! (20分)

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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

题目解析:
条件一:必须只能包含P、A、T三个字符,这个好理解。

条件二:形如xPATx,x为空或A组成的字符串,注意左右两个x相同,即PAT左边几个A右边也得几个A,也不难理解。

条件三:如果aPbTc是正确的,那么aPbATca也是正确的,abc全为空或全为A组成的字符串。

接下来细讲条件三:

条件三说如果aPbTc是正确,很多人就不明白"如果"了,这就用到条件二了,因为条件二可以确定100%答案正确的字符串。由条件二可以知道

PAT APATA AAPATAA AAAPATAAA ……都是正确的

① ② ③ ④ (我编一个号)

接下来我用条件三拿①PAT举个例子,重点来了:

如果aPbTc=PAT,那么a=空,b=A,c=空,带入aPbATca得PAAT正确,如果PAAT正确,那么令PAAT=aPbTc,得a=空,b=AA,c=空,带入aPbATca得PAAAT正确,依次带下去可得PAAAA……T都是正确的。

怕大家还是不理解,我用②再举个例子:

如果APATA=aPbTc,那么a=A,b=A,c=A,带入aPbATca得APAATAA正确,如果APAATAA正确,令APAATAA=aPbTc,则a=A,b=AA,c=AA,带入aPbATca得APAAATAAA正确,依次下去……

文字很乱,下面我来画一个图:

图片

下面找规律:

图片

第一个数字代表P之前A的个数,第二个数字代表P和T之间A的个数,第三个数字代表T之后A的个数,观察可得:第一个数字*第二个数字=第三个数字。

AC代码:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner s=new Scanner(System.in);
        int N=Integer.parseInt(s.nextLine());//读入第一行的数字
        String str[]=new String[N];
        for(int i=0;i<N;i++){
            str[i]=s.nextLine();//读入每行要判断的字符串,放到str数组中
        }
​
        for(int i=0;i<str.length;i++){
            boolean flag=true;
            //分别记录P和T字母的位置
            int pos_P=0,pos_T=0;
            //分别记录P和T字母的个数,之所以要记录个数就是为了不用判断P之前,PT之间,T之后全是A
            //因为如果P和T都只有一个,再加上条件一的约束,剩下的自然全是A,简化代码
            int count_P=0,count_T=0;
            char c[]=str[i].toCharArray();
            for(int j=0;j<c.length;j++){
                //每一个字母是P、A、T中的一个
                if(c[j]=='P'||c[j]=='A'||c[j]=='T'){
                    if(c[j]=='P'){
                        pos_P=j; //记录P的下标
                        count_P++;//记录P的个数
                    }
                    if(c[j]=='T'){
                        pos_T=j;    //记录T的下标
                        count_T++; //记录T的个数
                    }
                }else{
                    flag=false;//判断如果有一个字母既不是P也不是A也不是T就记flag为false,然后跳出循环
                    break;
                }
            }
            if(flag){ //flag为true,就说明字符串中的字母全为P、A、T,如果为false就说明还有别的字母,直接输出NO
                if(count_P==1&&count_T==1&&pos_T-pos_P>1){//保证P的个数,T的个数都为一,
                    //还要pos_T-pos_P>1,一来保证T字母一定在P字母的后边,另一方面防止PT这种情况
                    if(pos_P*(pos_T-pos_P-1)==(c.length-1-pos_T)){//此题最重要的部分
                        //pos_P就是P之前A的个数,pos_T-pos_P-1就是P与T之间A的个数,c.length-1-pos_T就是T之后A的个数
                        System.out.println("YES");
                    }else{
                        System.out.println("NO");
                    }
                }else{
                    System.out.println("NO");
                }
            }
            else{
                System.out.println("NO");
            }
        }
    }
}

这题自我感觉写的还是满详细的,此题的难点也是条件三不好理解,理解好之后这道题就迎刃而解了。再祝大家元宵节快乐,如果条件三有什么不理解的地方可以给我留言,我看到了会第一时间回复的。

关注公众号”算法宝贝“获取更多题目解析

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值