首页 > 试题广场 >

1003. 我要通过!(20)

[编程题]1003. 我要通过!(20)
  • 热度指数:4027 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

输入描述:
每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。


输出描述:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
示例1

输入

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

输出

YES
YES
YES
YES
NO
NO
NO
NO
推荐
本题是数学推导类型

条件1就不说了,太简单了
条件2,xPATx是正确的类型,其中x是由n个A组成(n>=0),
所以AAPATAA都是正确的,并且P和T两边A的个数相等。

关键是条件3
如果aPbTc是正确的,那么aPbATca也是正确的,其中a,b,c都是n个A组成(n>=0)。

由条件2知,如果aPbTc是正确的,那么它必须满足条件2,
所以a的长度和c的长度必定是相等的,且b等于1。

另外可以根据P和T间A的个数,判断通过条件3迭代了几次,,,就是P和T间A的个数减去1。

在迭代的过程正,a保持不变,c每迭代一次,长度加a,因此可以推出才c最后的长度。

大致原理就是由xPATx ----> aPbTc ----> aPbATca

代码如下
import java.io.PrintStream;
import java.text.ParseException;
import java.util.Scanner;

public class Main {
	public static Scanner in = new Scanner(System.in);
	public static PrintStream out = System.out;

	public static boolean test(String line){
		if(line==null)
			return false;
		
		int i=0;
		int len = line.length();
		
		int pCount,aCount,tCount;
		pCount=aCount=tCount=0;
		
		for(i=0;i<len;++i){
			if(line.charAt(i)=='P'){
				++pCount;
				
			}else if(line.charAt(i)=='A'){
				++aCount;
				
			}else if(line.charAt(i)=='T'){
				++tCount;
				
			}else{
				// 不满足条件1: 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符
				return false;
			}
		}
		
		// P和T只能出现一次 ,且A的个数大于一次
		if(!(pCount==tCount && aCount>=1 && pCount==1 ))
			return false;
		
		int indexP = line.indexOf('P');
		int indexT = line.indexOf('T');
		
		int leftA = indexP; // P前面A的个数
		int rightA = len - indexT - 1; // T后面A的个数
		int middleA = indexT - indexP - 1; // P和T直间A的个数
		
		int n = middleA - 1; // 迭代次数
		if(rightA != n*leftA+leftA)
			return false;
		
		return true;
	}
	public static void main(String[] args) throws ParseException {
		int N = in.nextInt();
		in.nextLine(); // 读取空白符
		
		for(int i=0;i<N;++i){
			if(test(in.nextLine()))
				out.println("YES");
			else
				out.println("NO");
		}
		
	}
}

编辑于 2015-08-18 22:30:15 回复(2)
#include<stdio.h>
#include<string.h>
int main()
{
    char s[1001];
    int i,n,a,b,c;
    char *p;
    scanf("%d",&n); 
    for(i=0;i<n;i++)
    {
        scanf("%s",&s);
        if(!strcmp(s,"PAT")){printf("YES\n");continue;}   //条件一
 
                a=b=c=0;
                p=s;
                while(*p=='A'){a++;p++;}   //a为第一个p前a的个数
                if(*p=='P'){
                        p++;
                        while(*p=='A'){b++;p++;}   //b为夹在p和t之间的a的个数
                        if(*p=='T'){
                                p++;
                                while(*p=='A'){c++;p++;}   //c为t之后的a的个数
                                if(!(*p) && b>0 && c==a*b){printf("YES\n");continue;}  //条件三
                        }
                }
                printf("NO\n");
         
    }
    return 0;
}

发表于 2015-09-05 17:02:58 回复(1)
啥头像
设满足条件一后, ‘P'前边有na1 个 'A', ‘P'和’T‘之间有na2个’A‘, ’T‘后面有na3个’A‘
则有  na1 * na2 = na3 且na2>0
因为最开始正确的的子串是 na1 = na3  条件二的情况
根据条件三的样式, 中间每增加一个’A',  na3 += na1

所以     na1 * na2 = na3 且na2>0
def isOK(string):
    na = [0]*3; idx = 0; np = 0; nt = 0
    for i in string:
        if i == 'A':
            na[idx] += 1
        elif i == 'P':
            if np > 0:
                return False
            np += 1; idx += 1
        elif i == 'T':
            if np == 0 or nt > 0:
                return False    
            nt += 1; idx += 1
        else:
            return False
    if na[0]*na[1] == na[2] and na[1] > 0:
        return True
    return False

n = int(raw_input())
for i in range(n):
    string = raw_input().strip()
    if isOK(string):
        print('YES')
    else:
        print('NO') 


发表于 2016-01-17 22:21:14 回复(0)
在座的各位都没审题吧,人家是字符串全都输入完成之后再每个字符串进行判断输出,你们这可都是输一个判断一个啊,每一个对的。
#include <stdio.h>
 
int main(){
    int n;
    char q[10][100];
    int before = 0, inner = 0, after = 0;    //分别存放三处A的数量 
    int P = 0,T = 0;                        //存P和T的数量,同时作为PT是否出现的标志 
    int i, j;
    int a[10];                                //分别存放各个字符串的状态 1为正确 其他均为错误 
    scanf("%d",&n);
    for(i = 0; i < n; i++){
        a[i] = 0;
    }
    for(i = 0; i < n; i++){
        scanf("%s", &q[i]);
    }
    for(i = 0; i < n; i++){
        //循环之前初始化这些变量 
        before = 0; 
        after = 0;
        inner = 0;
        P = 0;
        T = 0;
        for(j = 0; q[i][j] != '\0'; j++) {
            //字符串中有其他字母 
            if(q[i][j] != 'P' && q[i][j] != 'A' && q[i][j] != 'T')
                a[i] = -1;
            //分别计算P和T的数量 并判断P和T的位置 
            else if(q[i][j] == 'P' && T == 0) P++;//T此时为0 保证P是在T前面 
            else if(q[i][j] == 'T' && P == 1) T++;
            //分别计算三处A的数量
            else if(q[i][j] == 'A') {
                if(P == 0 && T == 0)
                    before++;
                else if(P == 1 && T == 0)
                    inner++;
                else if(T == 1 && P == 1)
                    after++;
            }
                
        }
        //排除有其他字母的情况 
        if(a[i]==0){
            if(j < 3)
                a[i] = 0;//如果只含两个字母 那么说明一定没有PAT 
            else if(T != 1||P != 1)
                a[i] = 0;//P和T数量不对 或者位置不对 
            else if(after == before * inner)
                a[i] = 1; 
        }
    }
    for(i = 0; i < n-1; i++)
    {
        if(a[i]==1)printf("YES\n");
        else printf("NO\n");
    }
    if(a[n-1]==1)printf("YES");
    else printf("NO");
    return 0;
}



发表于 2019-01-29 23:08:28 回复(3)
这道题给我的感觉两种做法,第一是用正则表达式处理来做,会非常简单,但是因为正则表达式可读性太差加上有些遗忘,这里采用第二种方法,用程序来模拟词法构造问题即递归做法
条件1和条件2都好说(ps:条件2注意一定要判断有没有其他字符混入,这样也可能导致程序过不去)
条件3说的有些让人摸不到头脑,其实实际的意思是,条件3的第一个式子必须满足条件2成立,然后在P和T之间每增加一个A,就要把条件3第一个式子P的前缀复制一份添加到字符最后面,即条件3第二个式子,很显然,这其实是个递归条件,递归传参时把添加操作反过来就是解法了,条件1,2作为递归出口
#include<bits/stdc++.h>
using namespace std;
bool check(string str){
    int pi,ti;
    if(str.find("P")!=string::npos){
        pi=str.find("P");
    }else{
        return false;
    }
    if(str.find("T")!=string::npos){
        ti=str.find("T");
    }else{
        return false;
    }
    if(ti-pi==1)return false;
    int count=0;
    for(int i=pi+1;i<ti;i++){
        if(str[i]=='A')count++;
    }
    if(count==0)return false;
    int sum1=0,sum2=0;
    for(int i=0;i<pi;i++)if(str[i]=='A')sum1++;
    if(count==1){
        //条件2
  
        for(int i=ti+1;i<str.size();i++)if(str[i]=='A')sum2++;
        if(sum1!=sum2||sum1<pi)return false;
    }else{
        //条件3
        string s1;
        s1=str.erase(str.size()-1-sum1,sum1);
        s1.erase(s1.begin()+pi+1);
        return check(s1);
    }
    return true;
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        getchar();
        for(int i=0;i<n;i++){
            string s;
            getline(cin,s);
            check(s)?printf("YES\n"):printf("NO\n");
        }
    }
    return 0;
}


编辑于 2020-04-16 10:15:45 回复(0)

用正则匹配应该最简单了吧!

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        Pattern pattern = Pattern.compile("(A*)P(A+)T(A*)");
        boolean flag;
        while (n-- > 0) {
            String s = in.next();
            Matcher matcher = pattern.matcher(s);
            flag = matcher.matches()
                    && matcher.group(1).length() * matcher.group(2).length() == matcher.group(3).length();
            System.out.println(flag ? "YES" : "NO");
        }
    }
}
编辑于 2019-01-20 13:16:19 回复(1)
/*
刚开始误解了题意,后参考大神解答后才明白-_-
分析:由条件一,不妨设P之前的A的个数为a,PT之间的A的个数为b,T之后的A的个数为c
由条件二知:a=c,b=1
由条件二知:b增加1时有c+=a;
综上所述:a*b=c且b>0
*/
#include<stdio.h>
#include<string.h>
int main (){//the shorter,the better.
    int n,i,j,a,b,c,len;char s[100];
    for(;~scanf("%d",&n);)
       for (i = 0; i < n&&~scanf("%s",s);printf("%s\n",a*b==c&&b?"YES":"NO"),i++){
            for(len = strlen(s),a=b=c=j=0;j<len&&s[j]=='A';++j,++a);
            if(j<len-2&&s[j]=='P'&&s[j+1]=='A')
                for(++j;j<len&&s[j]=='A';++j,++b);
                if(j<len&&s[j]=='T')for(++j;j<len&&s[j]=='A';++j,++c);
       }
}

编辑于 2018-02-03 14:52:53 回复(0)
#include <iostream>
using namespace std;
int main(){
    char s[110];
    int n;cin>>n;
    while(n--){
        int str=0,aleft=0,amid=0,aright=0;
        cin>>s;
        for(int i=0;s[i];i++){
            if(s[i]=='P'&&str==0)            //P前面只能有A
                str=1;
            else if(s[i]=='A'){
                if(str==0) aleft++;         //统计P左边的A
                else if(str==1){            //统计P T中间的A
                    str=2;
                    amid++;
                }
                else if(str==2) amid++;
                else aright++;             //统计T右边的A
            }
            else if(s[i]=='T'&&str==2)     //T只能在A右边
                str=3;
            else break;
        }
        if(str==3 && aright==aleft*amid)   //中间有多少个A,右边就必须有多少倍左边A的数量
            cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

发表于 2018-02-14 16:14:36 回复(0)
我觉得我的代码足够简单
#include<stdio.h>
(737)#include<string.h>
int main()
{
	int i,j,n;
	char str[101];
	scanf("%d",&n);
	while(n--)
	{
		scanf("%s",str);
		int a=0,b=0,c=0,flag=1;
		int len=strlen(str);
		for(i=0;str[i]&&str[i]!='P';i++)//P左边A的数量
			if(str[i]=='A')
				a++;
			else
				flag=0;//P左边不是A
		for(j=len-1;str[j]&&str[j]!='T';j--)//T右边A的数量
			if(str[j]=='A')
				c++;
			else
				flag=0;//T右边不是A
		while(++i<j)//P和T之间A的数量
		{
			if(str[i]=='A')
				b++;
			else
				flag=0;//P和T之间不是A
		}
		if(flag==1&&a*b==c&&b)//b>0且符合推导公式
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}



编辑于 2020-04-15 19:44:39 回复(1)
#include<bits/stdc++.h>
using namespace std;
int main(){
	int N;
	while(cin>>N){
		for(int i=0;i<N;++i){
			string s;
			cin>>s;
			int sign = 0;
			int P = 0,PA = 0,PAT = 0;
			int Pi,Ai,Ti;
			map<char,bool>mp = {{'P',1},{'A',1},{'T',1}};
			for(int i=0;i<s.size();++i){
				if(!mp[s[i]])break;//不能包含其他字符
				if(s[i] == 'P'){
					Pi = i;
					P++;
				}
				if(s[i] == 'A'){
					if(!PAT)Ai = i;
					PA = P&1;
				}
				if(s[i] == 'T'){
					Ti = i;
					PAT = (PAT > 0)?PAT+1:PA&1;
				}
				if(P>1||PAT>1)break;//P、T数超过1
				if(PAT == 1&&i==s.size()-1){//满足条件1
					sign = 1;
					break;
				}
			}
			if(!sign){
				cout<<"NO"<<endl;
				continue;
			}
			string a,b,c;
			a = s.substr(0,Pi);
			b = s.substr(Pi+1,Ai-Pi-1);
			c = s.substr(Ti+1);
			if(a.size()*(b.size()+1) == c.size()){//满足条件2、3
				cout<<"YES"<<endl;
			}else cout<<"NO"<<endl;
		}
	}
}

发表于 2019-09-23 00:23:59 回复(0)
#include<cstdio>
#include<cstring>


void isTrue(char b[]){
    int p = 0, a = 0, t = 0;    // 确定P,A,T各个字符的个数 
    int len, weip, weit;  
    len = strlen(b);
    for(int i = 0; i < len; i++){
        if(b[i] == 'P'){
            p++                                                        ;
            weip = i;             //确定字符P的位置 
        }
        if(b[i] == 'A') a++;
        if(b[i] == 'T') {        //确定字符T的位置 
            t++;
            weit = i;
        }
     }
     int zuo = weip, you = len - weit - 1;    //zuo,you分别为左侧与右侧A字符个数
     if(p + a +t == len && p == 1 && t == 1 && a != 0) {   // 确保只含有P,A,T,三个字符,且排除只含PT的情况 
         if(zuo == you && weit - weip - 1 == 1){    //条件1。 weit - weip - 1为夹在PT之间A的个数 
             printf("YES\n");
        }else if(zuo == 0){                          //为了确保下一个elseif不会出现分母为零的情况 
            if(you == 0)  printf("YES\n");    
            else printf("NO\n");
        }else if(you % zuo == 0 && weit - weip - 1 == you / zuo){  //条件3 
            printf("YES\n");
        }else{
            printf("NO\n");
        }
    }else{
        printf("NO\n");
    }
     
}

int main(){
    int n;
    char s[200] = "";
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%s", s);
        isTrue(s);
    }
    return 0;
}
编辑于 2019-04-28 12:39:43 回复(0)
#include<bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin>>n;
	while(n--) {
		string str;
		cin>>str;
		int loc_P,loc_T,other=0,numP=0,numT=0,m=str.size();
		for(int i=0; i<m; i++) {
			if(str[i]=='P') {
				numP++;
				loc_P=i;
			} else if(str[i]=='T') {
				numT++;
				loc_T=i;
			} else if(str[i]!='A') {
				other++;
			}
		}
		if(numP>1||numT>1||other>0||loc_T-loc_P<=1) {
			cout<<"NO"<<endl;
		} else {
			int x=loc_P,y=loc_T-loc_P-1,z=m-1-loc_T;
			if(z-(y-1)*x==x) {
				cout<<"YES"<<endl;
			} else {
				cout<<"NO"<<endl;
			}
		}
	}
	return 0;
}

发表于 2022-11-14 20:37:29 回复(0)
已经不能再详细了
这题看了半天描述甚至没有懂它在表述什么,后来看了一个老哥的代码豁然开朗:

形如xPATx这样的符合,两个x之间长度要一致
xPATx中间的PAT每加上一个A变为PAAT时,都需要将原来的xPATx变为xPAATxx,以此类推。


归 纳 整 理 后 我 们 可 以 的 到 一 个 公 式 : P 前 面 的 字 符 串 个 数 ∗ A 的 个 数 = T 后 面 的 字 符 串 个 数 归纳整理后我们可以的到一个公式: P前面的字符串个数*A的个数=T后面的字符串个数
归纳整理后我们可以的到一个公式:P前面的字符串个数∗A的个数=T后面的字符串个数

所以符合上式的输入即为合格输入
由此想到我们可以想到用java里的正则表达式完成这一题

发表于 2021-08-02 22:36:45 回复(0)

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

int main(){
    int i,n,len; string s;
    int count_x;//记录P之前A的数量
    int count_b;//记录PT中间A的数量
    int count_c;
    cin>>n;
    while(n--){
        cin>>s; len = s.length();
        count_x = 0; count_b = 0; count_c=0;
        for(i=0;i<len&&s[i]=='A';i++) count_x++;
        if(len==i||s[i]!='P') {cout<<"NO"<<endl;continue;}
        for(i=i+1;i<len&&s[i]=='A';i++) count_b++;
        if(len==i||s[i]!='T') {cout<<"NO"<<endl;continue;}
        for(i=i+1;i<len&&s[i]=='A';i++) count_c++;
        if(i<len) cout<<"NO"<<endl;
        else if(count_b>0&&count_b*count_x==count_c) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}


编辑于 2021-07-25 18:37:19 回复(0)
在PTA上做的,当时看到题目直接看不懂了,明明每个字都认识,连在一起却看不懂了QAQ..网上找了大佬的解析明白了题目的意思是这样的:P左边A的个数乘以P和T之间A的个数等于T右边A的个数,使用三个条件进行推导好像确实是这样的,然后我用C++进行了如下的实现,奇怪的是,我在PTA上只有一部分测试用例通过了,但是在牛客上通过了全部的测试用例,我在找找bug吧555,各位牛友们有看出来的告诉我一声啊,不胜感激:
#include<iostream>
#include<string>

using namespace std;
bool isRight(const string s);
bool isPAT(char c);

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        string str;
        cin >> str;
        cout << (isRight(str) ? "YES" : "NO") << endl;
    }
    return 0;
}

bool isRight(const string s) {
    string P = "";
    string A = "";
    string T = "";
    int p = 1, a = 0, t = 0;
    for(auto ch : s) {
        if(!isPAT(ch))
            return 0;
        if('A' == ch) {
            if(1 == p)
                P = P + ch;
            else if(1 == a)
                A = A + ch;
            else
                T = T + ch;
        }
        else if('P' == ch) {
            a = 1;
            p = 0;
        }
        else {
            t = 1;
            a = 0;
        }
    }
    if(!A.empty() && (A.size() * P.size() == T.size()))
        return 1;
    else
        return 0;
}
bool isPAT(char c) {
    if (c != 'P' && c != 'A' && c != 'T')
        return 0;
    return 1;
}


发表于 2021-03-25 10:32:00 回复(0)
import re


def judge(s: str):
    lt = list(s)
    l = [x for x in lt if x != 'P' and x != 'A' and x != 'T']
    if len(l) > 0:
        return False
    if s == 'PAT':
        return True
    if re.match('A*PATA*', s) is not None:
        t1, t2 = s.split("PAT")
        if t1 == t2:
            return True

    if re.match('A*PA*ATA*', s) is not None and len(s) > 3:
        num = s.find('P')
        lst = list(s[:len(s)-num])
        i_T = s.find('T')
        del lst[i_T - 1]
        t3 = "".join(lst)
        if judge(t3):
            return True
    return False


n = int(input())
for i in range(n):
    x = str(input())
    if judge(x):
        print("YES")
    else:
        print("NO")

发表于 2021-01-20 17:14:49 回复(0)
题中:
APAAATAA
怎么错误了呢?
他满足条件1、条件2、也满足条件3
发表于 2020-05-04 08:47:54 回复(1)


这道题关键切入点是统计字符'P'、‘T'前后、中间的字符’A‘的个数。

首先由条件2 “xPATx”,x是空白字符串或者是由字符’A‘组成的字符串。
==总的来说就是"PAT"字符串的’A'字符数相等。==
形如“PAT”“APATA”等都是正确的。

再看条件3,如果“aPbTc”是正确的,根据规则2可知b = ‘A'a = c = xx是空白字符串或者是由字符’A‘组成的字符串),那么aPbATca也是正确的,我们再递推一次得到aPbAATcaa,肯定也是正确的。

仔细对比“aPbTc”aPbATcaaPbAATcaa,不难发现,当在b后面加一个字符'A'时,就得在c的后面增加一个a

由于b = ’A',==假设aPbATca字符串中P、T之间A的个数k,那么字符T之后的A个数是字符P之前A的个数的k倍。==

#include <iostream>
(720)#include <cstring>
using namespace std;

int main() {
    int n = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        char str[101] = {'\0'};
        scanf("%s", str);
        //分别统计字符P之前、字符P与字符T之间、字符T之后的A字符个数
        int j = 0, beforeACount = 0, centerACount = 0, afterACount = 0, strLength = (int)strlen(str);
        //统计字符P之前的A字符个数
        while (j < strLength && str[j] == 'A') {
            j += 1;
            beforeACount += 1;
        }
        //如果没遇到字符P就到结尾,或者其他字符,该字符串都是错误的
        if (j >= strLength || str[j++] != 'P') {
            printf("NO\n");
            continue;
        }
        //统计字字符P与字符T之间的A字符个数
        while (j < strLength && str[j] == 'A') {
            j += 1;
            centerACount += 1;
        }
        //如果没遇到字符T就到结尾,或者其他字符,该字符串都是错误的
        if (j >= strLength || str[j++] != 'T') {
            printf("NO\n");
            continue;
        }
        //统计字符T之后的A字符个数
        while (j < strLength && str[j] == 'A') {
            j += 1;
            afterACount += 1;
        }
        //如果没有达到结尾,说明遇到了其他字符,如果字符P与字符T之间A字符数为0,也是错误的
        if (j != strLength || centerACount == 0) {
            printf("NO\n");
            continue;
        }
        //如果centerACount == 1,则beforeACount == afterACount
        //假设`aPbATca`字符串中P、T之间A的个数k,那么字符T之后的A个数是字符P之前A的个数的k倍。
        //如果centerACount > 1,则centerACount * beforeACount == afterACount
        //合并之后的条件就是判断 centerACount * beforeACount != afterACount
        if (centerACount * beforeACount != afterACount) {
            printf("NO\n");
            continue;
        }
        printf("YES\n");
    }
    return 0;
}
————————————————
版权声明:本文为CSDN博主「hestyle」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://hestyle.blog.csdn.net/article/details/104753529
发表于 2020-03-09 15:52:42 回复(0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
/**
 * 1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
 * 2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
 * 3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
 **/
 
////A(m)PA(i)TA(m*i)
int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        for(int z = 0; z < n; z++)
        {
            char pat[100];
            scanf("%s", pat);
            int count1 = 0, count2 = 0, count3 = 0;
            int c1_end = 0, c2_end = 0;
            int j = 0;
            int tj = 1;
            while(pat[j] != '\0')
            {
                if(pat[j] != 'P' && pat[j] != 'A' && pat[j] != 'T')
                {
                    tj = 0;
                    break;
                }
                j++;
            }
            if(!tj)
            {
                printf("NO\n");
                continue;
            }
            //只有pat三个字母,tj = 1
            j = 0;
            int p_count = 0, t_count = 0;
            while(pat[j] != '\0')
            {
                if(p_count < t_count || p_count > 1 || t_count > 1)
                {
                    tj = 0;
                    break;
                }
                if(pat[j] == 'P')
                    p_count++;
                else if(pat[j] == 'T')
                    t_count++;
                j++;
            }
            if(!tj || p_count != 1 || t_count != 1)
            {
                printf("NO\n");
                continue;
            }
            //p和t只有一个,且p在t前, tj = 1
            j = 0;
            while(pat[j] != '\0')
            {
                if(pat[j] == 'P')
                    c1_end = 1;//第一坨A计数完毕
                else if(pat[j] == 'T')
                    c2_end = 1;//第二坨A计数完毕
                else if(pat[j] == 'A')
                {
                    if(c1_end == 0)
                    {
                        count1++;
                    }
                    else if(c2_end == 0)
                    {
                        count2++;
                    }
                    else
                    {
                        count3++;
                    }
                }
                j++;
            }
            if(count3 == count1 * count2 && count2 != 0)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }
    return 0;
}

编辑于 2020-03-04 17:41:17 回复(0)
分析同上, 不赘述.
C++解答, 如果不喜欢看C风格代码可以看看这个.
#include <iostream>
#include <string>
using namespace std;
int main(){
    int n;
    cin>>n;
    while(n--){
        int index_p=0,index_t=0;
        int before_p=0,between_pt=0,after_t=0;
        int p_set=0,t_set=0;
        string str;
        cin>>str;
        for(unsigned i=0;i<str.length();++i){
            if(str[i]!='P'&&
               str[i]!='A'&&
               str[i]!='T'){
                   cout<<"NO"<<endl;
                   break;
            }
            if(str[i]=='P'){
                index_p=i;
                ++p_set;
                if(p_set>1){
                    cout<<"NO"<<endl;
                    break;
                }
            }
            if(str[i]=='T'){
                index_t=i;
                ++t_set;
                if(t_set>1){
                    cout<<"NO"<<endl;
                    break;
                }
            }
            if(p_set&&t_set){
                before_p=index_p;
                between_pt=index_t-index_p-1;
                after_t=str.length()-index_t-1;
                if(after_t!=before_p*between_pt||index_p+1==index_t){
                    cout<<"NO"<<endl;
                    break;
                }
                else{
                    cout<<"YES"<<endl;
                    break;
                }
            }
            if((i==str.length()-1)&&!(p_set&&t_set)){
                cout<<"NO"<<endl;
                break;
            }
        }
    }
    return 0;
}


发表于 2019-04-02 17:08:08 回复(0)
  • 贴个C++ 的regex
    (a)P(b)T(c)
    子匹配(b)每增加一个A,
    子匹配(c)增加len(a)个A,
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
    ios::sync_with_stdio(0);
    int n;
    string t = "";
    regex e("(A*)P(A+)T(A*)");
    cin >> n;
    cin.ignore();
    for(int i = 0; i < n; i++)
    {
        cmatch cm;
        getline(cin, t);
        if(regex_match(t.c_str(), cm, e, regex_constants::match_default))
        {
            if(cm[2].length()>0 && cm[1].length()*cm[2].length()==cm[3].length())
                puts("YES");
            else
                puts("NO");
        }
        else
            puts("NO");
    }
    return 0;
    }
    

```

编辑于 2019-03-15 21:18:52 回复(0)