1003 我要通过!

题目链接:1003 我要通过!

思路分析:

1、字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符

分析:字符串只能由这三种字符组成,在判断的过程中,如果出现了其他字符,那么该字符串不符合规范。

2、任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;

分析:

(1)当x表示空的时候,字符串表示的是PAT,字符串是正确的

(2)当x表示A的时候,字符串表示的是APATA,字符串是正确的

(3)当x表示AA的时候,字符串表示的是AAPATAA,字符串是正确的

(4)当x表示AAA的时候,字符串表示的是AAAPATAAA,字符串是正确的

(5)后面依次类推,注意P的前面和T的后面都是x,表达的意思就是P前面A的数量和T后面A的数量是一样的。

3、如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

(1)P前面是a,P和T之间是b,T后面是c;a,b,c是由A组成的字符串或者空串,a,b,c三者之间可以相同,也可以完全不同。

(2)可不可以三者都是空串呢?根据测试用例PT得到的结果是NO,PAT得到的是YES,可以看出,P和T之间一定要有A。

(3)根据第(2)点,我们可以看出,P和T之间一定要有A,P的前面和T的后面可以是空,那么中间A是否只能有一个呢?根据测试样例PAAT是YES,PAT也是YES,可以推测,PxT都是对的,其中x由A组成,且至少有一个A,可以有多个A。

(4)在第(3)点中,我们推测,当P前面和T后面都是空串的时候,P和T之间至少要有一个A。那aPbTc中,可以确定b不可以为空串,a,c可以为空串。根据题目意思aPbATca也是对的,我们和aPbTc对比,P和T之间加了一个A,T后面加了一个a。那么推测,当P和T之间再加一个A,得到的是aPbAATcaa,当P和T之间再加一个A,得到的是aPbAAATcaaa,并且b也是由A组成的字符串。

(5)在第(4)点中,我们可以得到aPbTc是正确的,那么aPbAAATcaaa也是正确的。接下来看测试用例,AAPATAA是正确的,此时a是AA,b是A,c是AA。b由一个A组成,那么c=a。AAPAATAAAA是正确的,此时a是AA,b是AA,c是AAAA,c可以看作是由两个a组成。APAAATAA是错误的,此时a是A,b是AAA,c是AA。

(6)我们结合xPATx中x由若干个A组成正确的,因此aPbTc中当b等于一个A的时候,a等于c,aPbTc可以写成aPbTa。aPbTc中P和T之间每增加一个A,最末尾增加一个c,可以将P和T之间字符串b可以拆分成A+若干个A,那么aPbTc就变成了aPA+(若干个A)Ta+(若干个a),进行总结,aPbTc可以写成aP(N个A)T(N个a),也就是c=(b中A的数量)*a,由于a、b、c都是由A 组成的字符串。因此a,b,c三者之间的关系是len(c) = len(b)*len(a),也就是a中A的数量*b中A的数量=c中A的数量。

最后我们根据测试用例总结一下正确的字符串应该具备的条件:

(1)字符串只能由P、A、T三种字符组成(根据题目给出的条件一和测试用例xPATx错误、测试用例Whatever错误得出)

(2)字符串P、A、T三种字符必须都出现,P和T之间一定要有A(根据测试用例PT错误、APT错误、PAT正确、PAAT正确得出)

(3)字符串P和T只能出现一次(根据测试用例APATTAA错误得出)

(4)P在T的前面(根据PAT正确、PAAT正确、AAPATAA正确、AAPAATAAAA正确得出)

(5)P前面A的数量*P和T之间A的数量=T后面A的数量(根据PAT正确、PAAT正确、AAPATAA正确、AAPAATAAAA正确、APAAATAA错误得出)

代码一:

def judge(s):
    cnt_p,cnt_a,cnt_t = 0,0,0
    index_p,index_t = -1,-1
    for i in range(len(s)):
        c = s[i]
        #如果有非P A T 字符,那么该字符串不符合要求
        if c != 'P' and c != 'A' and c != 'T':
            #print(s)
            return False
        if c == 'P':
            cnt_p += 1
            index_p = i
        if c == 'A':
            cnt_a += 1
        if c == 'T':
            cnt_t += 1
            index_t = i
    #如果有P或者A字符的数量大于1,那么该字符串不符合要求
    if cnt_p > 1 or cnt_t > 1:
        #print(s)
        return False
    #如果有P和T之间没有字符A,那么该字符串不符合要求
    if index_p+1 == index_t:
        #print(s)
        return False
    #如果有P在T后面,那么该字符串不符合要求
    if index_p > index_t:
        #print(s)
        return False
n = int(input())
for _ in range(n):
    s = input()
    if judge(s) == False:
        #print(s)
        print('NO')
        continue
    index_p = s.find('P')
    index_t = s.find('T')
   # print('{}  {} {} {} {}'.format(index_p,index_t,index_p,index_t - index_p - 1,len(s) - index_t-1))
    #如果P前面的A的数量(index_p) * P和T之间的A的数量(index_t - index_p - 1) = T后面A的数量(len(s) - index_t-1)
    if index_p * (index_t - index_p - 1)== len(s) - index_t-1:
        print('YES')
    else:
        print('NO')
    

方法二:使用正则表达式

根据题目意思:

(1)P前面有零个或者多个A,为A*P

(2)T后面有零个或者多个A,为TA*

(3)P和T之间至少有一个A为,PA+T

(4)整个字符串只有一个P和T

(5)因此整个字符串模板为:A*PA+TA*

(6)根据P和T进行分段a=re.split(r'[P|T]',s)

(6)符合这个模式的字符串进一步判断:P前面A的数量*P和T之间A的数量=T后面A的数量是否成立。len(a[0])*len(a[1])==len(a[2])是否成立

import re  
n=input()  
for i in range(int(n)):  
    s=input()  
    if re.match(r'A*PA+TA*',s): #在字符串中进行匹配 
        a=re.split(r'[P|T]',s)  #以字符P,T进行分段
        #print('{} {} {}'.format(a[0],a[1],a[2]))
        if len(a[0])*len(a[1])==len(a[2]):  #条件判断
            print('YES')  
        else:  
            print('NO')  
    else:  
        print('NO') 

  • 86
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值