PAT乙级 1003 我要通过!数学问题

在这里插入图片描述
在这里插入图片描述

题意:

给出一个字符串,可能有P、A、T或其他字符,现在需要根据以下几个条件来判断是否输出“YES”
条件1:如果出现P,A,T之外的字符,输出“NO”;初始状态下P和T必须各恰有一个,且P在T左边,P和T之间至少有一个A,否则输出“NO”
条件2:PAT,APATA,AAPATAA,AAAPATAAA,…,xPATx都输出“YES”,这里x为空或是任意数量的A
条件3:假设有一个字符串的格式是aPbTc,这里的a,b,c可以为空或是任意数量的A。如果这个字符串aPbTc已知是YES,那么在b和T之间添加一个A,c后面添加字符串a之后形成的新字符串aPbATca也是YES。

思路:

在这里插入图片描述
从图中可以看出,条件2给出的字符串是最底层YES的,且条件2的P与T中间有且只有一个A,而由条件3得到的所有字符串一开始一定是从条件2中的字符串变形而来。
所以我们记录P左边A的个数x,P和T中间A的个数为y,T右边A的个数为z。
考虑到条件3得到的新字符串的过程是在PT中间加一个A,字符串后面加上P前面所有的A,因此,我们每使用条件3一次,x不变,y=y+1,z=z+x。我们如果顺着箭头逆回去,每逆一次,x不变,y=y-1,z=z-x,这样一直逆到y=1,这时我们判断x和z是否相等,如果x==z,则输出“YES”,否则输出“NO”
因为y每次减1,所以要减到1,需要进行y-1次回退,而T右边的A的个数z在经过y-1次回退后(z每次减x)将变为z-x*(y-1)。我们只需要判断z-x*(y-1)==x是否成立即可。

代码如下:

#include<iostream>
#include<stdio.h>
#include<vector>
#include<string.h>
#define MAX 1000000
using namespace std;

int main(){
    int T;
    scanf("%d",&T);//输入字符串
    getchar();
    while(T--){
        char str[110];
        scanf("%s",str);
        int len=strlen(str);
        //分别代表P的个数、T的个数、除PAT外字符的个数
        int num_p=0,num_t=0,other=0;
        int loc_p=-1,loc_t=-1;//分别代表P的位置、T的位置
        for(int i=0;i<len;i++){
            if(str[i]=='P'){
                num_p++;
                loc_p=i;
            }else if(str[i]=='T'){
                num_t++;
                loc_t=i;
            }else if(str[i]!='A'){
                other++;
            }
        }
        //如果P的个数不为1,或者T的个数不为1,
        //或者存在除PAT之外的字符,或者P和T之间没有字符
        if(num_p!=1||num_t!=1||other!=0||(loc_t-loc_p)<=1){
            printf("NO\n");
            continue;
        }
        int x=loc_p,y=loc_t-loc_p-1,z=len-loc_t-1;
        if(z-x*(y-1)==x){
            printf("YES\n");
        }else{
            printf("NO\n");
        }
    }
    return 0;
}

发布了253 篇原创文章 · 获赞 15 · 访问量 7993

猜你喜欢

转载自blog.csdn.net/weixin_44123362/article/details/103897314