C/C++:PAT刷题集(乙级)1003 我要通过!(20 分)

题目及要求

“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (≤10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。
输入样例:
10
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
APATTAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO

前言

这个题目的描述有一点不太清楚,需要多读几遍题目,在这里有三个条件,前面两个条件比较好理解一点,主要在于最后一个
1:P A T 三个字母必须都有,且只有这三个字母 且 P T 只能出现一次
2: P 和 T 之间必须至少有一个A
最后一个需要去找一下规律,aPATa的基础上 中间每多一个A 后面就要多出一个前面的a
例如:APATA,P前面(前段)和中间分别有一个A,那么11=1 即前段A的数量中段A的数量等于后段A的数量
APAATAA:前段有一个A,中段有两个A,则后段有也有两个A:也就是12=2
AAPAATAAAA:前段有两个A,中段有两个A,后段有四个A:也就是2
2=4
根据输入案例去进行找规律即可知道:前段部分*中段部分=后段部分

解题思路

在该程序中,我们首先定义了一个名为 is_correct 的函数,用于判断一个字符串是否符合题目要求。该函数接受一个字符串作为输入,并返回一个布尔值,表示该字符串是否符合要求。
在函数中,我们首先使用两个变量 count_p 和 count_t 来统计字符串中 P 和 T 的数量,并使用两个变量 pos_p 和 pos_t 来记录它们的位置。如果字符串中包含除 P、A、T 以外的其他字符,则直接返回 false。
接下来,我们判断字符串是否符合 xPATx 的形式,即 P 和 T 之间必须至少有一个 A。如果不符合,则返回 false。
最后,我们判断字符串是否符合 aPbATca 的形式,即字符串可以被分成三个部分,左边部分由若干个 A 组成,中间部分由一个 P 和若干个 A 组成,右边部分由若干个 A 和一个 T 组成,并且左边部分与中间部分的长度乘积等于右边部分的长度。如果不符合,则返回 false。
在主函数中,我们首先读入测试数据的数量 n,然后依次读入每个测试数据,并调用 is_correct 函数判断其是否符合要求。如果符合,则输出 YES,否则输出 NO。

#include <iostream>
#include <string>
using namespace std;

// 判断字符串是否符合要求的函数
bool is_correct(string s) {
    int count_p = 0, count_t = 0;  // 统计 P 和 T 的数量
    int pos_p = -1, pos_t = -1;    // 记录 P 和 T 的位置
    for (int i = 0; i < s.length(); i++) {  // 遍历字符串中的每个字符
        if (s[i] == 'P') {  // 如果当前字符是 P
            count_p++;      // P 的数量加一
            pos_p = i;      // 记录 P 的位置
        } else if (s[i] == 'T') {  // 如果当前字符是 T
            count_t++;      // T 的数量加一
            pos_t = i;      // 记录 T 的位置
        } else if (s[i] != 'A') {  // 如果当前字符不是 P、A、T 中的任何一个
            return false;   // 字符串不符合要求,返回 false
        }
    }
    if (count_p != 1 || count_t != 1 || pos_t - pos_p <= 1) {  // 如果 P 或 T 的数量不为 1,或者它们之间的距离小于等于 1
        return false;   // 字符串不符合要求,返回 false
    }
    int len_left = pos_p;   // 计算前段部分的长度
    int len_mid = pos_t - pos_p - 1;  // 计算中段部分的长度
    int len_right = s.length() - pos_t - 1;  // 计算后段部分的长度
    if (len_left * len_mid != len_right) {  // 如果前段部分和中段分的长度乘积不等于后段部分的长度
        return false;   // 字符串不符合要求,返回 false
    }
    return true;    // 字符串符合要求,返回 true
}

int main() {
    int n;
    cin >> n;   // 读入测试数据的数量
    for (int i = 0; i < n; i++) {   // 循环读入每个测试数据
        string s;
        cin >> s;   // 读入当前测试数据
        if (is_correct(s)) {    // 如果当前测试数据符合要求
            cout << "YES" << endl;  // 输出 YES
        } else {    // 如果当前测试数据不符合要求
            cout << "NO" << endl;   // 输出 NO
        }
    }
    return 0;
}

总结

这个题目主要在于理解题目意思,其它都不是什么大问题,认真阅读即可。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是念念i

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

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

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

打赏作者

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

抵扣说明:

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

余额充值