1003 我要通过!(20分)

1003 我要通过!(20分)

1003 我要通过! (20 分)

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

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

  1. 字符串中必须仅有 PAT这三种字符,不可以包含其它字符;

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

  3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 abc 均或者是空字符串,或者是仅由字母 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

分析:该题是一个字符串判断,处于内存大小考虑,本次采用依次读取字符处理的方式。题目的判断在三个条件之中,下面依次分析分析题目给出的三个条件:

第一个条件要求字符串中必须含有P、A、T三个字符,因此可以采取在输入字符时注意判断字符,若字符为P、A、T之一,则将对应的计数整数加一,若出现了其他字符,则将字符标识归零。

第二个条件为"xPATx"格式,x代表多个A字符串或空字符串,在PAT两端x字符串相同,可以单纯将前后两部分看作相同数目A组成的字符串,令两端字符串长度同时为a(a>=0),因此整体中三部分A字符串可以看作a*1=a的形式。

第三个条件为"如果 aPbTc 是正确的,那么 aPbATca 也是正确的",本一条件主要规范了对字符串的化简,具体判断还是由前两条条件所规定,因此主要注意该条件中对字符串的化简,这里需要注意字符串整体可以多次简化求解,即"AAPAAAATTAAAAAA"一次简化为"AAPAATAAAA"不能确定结果,再次简化后得出的字符串"AAPATAA"即可符合第二个条件,因此源字符串"答案正确",与第二个条件相似,所有的a、b、c都可以看作零个或多个A所组成的字符串,因此可以看出PT前后两部分(令前中后各部分A字符串长度分别为a、b、c)完全符合a*b=c的公式。

综合上述各条件分析,可以看出判断字符串可以从字符种类、统计三部分字符串长度并据a*b=c公式判断,但同时需要注意PT间的A字符串长度必须大于等于零,且PT顺序必须是P位于T前,因此在判断时需要加上这些条件,综合所有分析便可以得出以下代码:


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

void solve() {
   int x;
   char c;
   cin >> x;
   getchar();
       for (int i = 0; i < x; i++) {
           int begin = 0, mid = 0, end = 0;
           int P, A, T;
           P = A = T = 0; //P、A、T三个字母的个数
           int rp = 1; // 三部分A的标识,用以划分三个部分
           int cnd = 1; // 字符串内是否只含有P、A、T三个字母的标识
           int flag = 1;   //字母顺序标识符
           for (char s; s = getchar(), s != '\n';) {
               s == 'P' ? P++, rp = 2 : s == 'A' ? A++ : s == 'T' ? T++, rp = 3 : cnd = 0;//判断输入字符种类,从而改变对应数据
               if ((T >= 1) && (P == 0))   //判断P、T的前后顺序,若T出现在P前面则将标识符归零
                   flag = 0;
               switch (rp) {
               case 1:begin++; break; // 前
               case 2:if (s != 'P') mid++; break; // 中
               case 3:if (s != 'T') end++; break; // 后
              }
          }
           //总和判断,包括字符种类只有P、A、T,P、T只能出现一次,begin*mid=end乘法的满足,P、T的字符顺序,类似APT格式P前有A但PT间不存在A而能满足乘法的情况
           if (P == 1 && A && T == 1 && begin * mid == end && cnd&&flag&&mid)                
               printf("YES\n");
           else  // 否则
               printf("NO\n");
      }
}
int main() {
solve(); // 默默不说话的函数。
return 0;
}
posted @ 2021-05-30 14:06  sazkuyo  阅读(71)  评论(0编辑  收藏  举报