1003 我要通过! (20 分)

2 篇文章 0 订阅

1003 我要通过! (20 分)

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

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

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

输入样例
9
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
结尾无空行
输出样例
YES
YES
YES
YES
NO
NO
NO
NO
NO
结尾无空行

没看懂题目的小伙伴可以看看我的推导过程 我也想了一会儿 尽量讲清楚
逻辑分析
要求:
1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
2.任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3.如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
前提:
如果 aPbTc 是正确的,
结论:
那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

定义一个flag作为判定 flag=1时输出YES flag=0时输出NO

1.出现别的字符 直接判定flag=0(要求1)
2.a==c a和c是任意个a(要求2中x在首尾 对应要求3)
3.要求3由2推导 若成立 则b为A
用前式推导后式正确
第一次XPATX–>aPbTc–>aPbATca
推导得 a=c b=A aPbATca=aPAATac
第二次 aPAATac = aPbTac–> aPbATaac
推导得 b=AA aPbATaac=aPAAATaac
a在每一次推导过程中会迭代 后面得a会增加 b是任意个A
b一开始是A 推导过程中依次+A 依次增加的 所以 当a=A b=A或AA c=A或AA
所以 在 任意aPbTc 中
a*b=c

下面是c++ 比较简洁的解法
和常规方法比起来 判断条件写的更通透 用的映射

#include <iostream>
#include <map>
using namespace std;
int main() {
    int n, p = 0, t = 0;
    string s;
    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> s;
        map<char, int> m;
        for(int j = 0; j < s.size(); j++) {
            m[s[j]]++;
            if (s[j] == 'P') p = j;
            if (s[j] == 'T') t = j;
        }
        if (m['P'] == 1 && m['A'] != 0 && m['T'] == 1 && m.size() == 3 && t-p != 1 && p * (t-p-1) == s.length()-t-1)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

下面是常规思路解法 c++

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    int n,i,j,x1,x2,cnt1=0,cnt2=0,flag=1,cnt3,cnt4,cnt5;//假设答案正确
    char a[101];
    cin>>n;
    for(i=0;i<n;i++)
    {
        cnt1=0;
        cnt2=0;
        flag=1;
        cin>>a;
        for(j=0;j<strlen(a);j++)
        {
        if(a[j]!='P'&&a[j]!='A'&&a[j]!='T')
        {
            flag=0;
            break;
        }
            if(a[j]=='P')
            {
                x1=j;//p的位置
                cnt1++;//p的个数
            }
            if(a[j]=='T')
            {
                x2=j;//t的位置
                cnt2++;//t的个数
            }
        }
        if(cnt1!=1||cnt2!=1||x2-x1==1)
            flag=0;
        else
        {
            cnt4=x2-x1-1;//中间a的个数是p和t位置相减-1(位置从0开始)
            cnt3=x1;//前面a的个数是p的位置
            cnt5=strlen(a)-x2-1;//后面a的个数 是整个减t的位置-1(位置从0开始)
            if(cnt3*cnt4!=cnt5)//由题找规律可知,正确答案中前面的A的数量×中间的A的数量=后面的A的数量
                flag=0;
        }
        if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜小爷�

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值