【PAT】我要通过!

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

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

1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

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

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

输入样例:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

输出样例:

YES
YES
YES
YES
NO
NO
NO
NO

初看题目我是这么理解的:

  • 由条件 (1) (2) 知,有 2 种基本情况是 “正确” 的,即 PAT 和 xPATx;
  • 由条件 (3) 知,其余 “正确” 情况都是由那 2 种基本情况不断演变而来。

因此我想到的是递归暴力法:

  • 首先判断 2 种基本情况为 “正确”。
  • 要想 aPbATca “正确”,就要 aPbTc “正确”,于是用 string.find() 找到 aPbATca 中 ‘P‘ 和 ‘AT‘ 的下标,通过 string.substr() 截取字符串获得 aPbTc,递归判断 aPbTc 是否 “正确”。
 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 bool onlyA(string s) {
 7     for (int i = 0; i < s.size(); i++)
 8         if (s[i] != ‘A‘)
 9             return false;
10     return true;
11 }
12
13 bool isCorrect(string s) {
14     if (s == "PAT")  return true;
15     else if (s.find("PAT") != string::npos) {
16         int idx = s.find("PAT");
17         string x1 = s.substr(0, idx), x2 = s.substr(idx + 3);
18         if (onlyA(x1) && onlyA(x2) && x1 == x2)
19             return true;
20     }
21     else if (s.find("P") != string::npos) {
22         int p_idx = s.find("P");
23         string a1 = s.substr(0, p_idx);
24         string a2 = s.substr(s.size() - p_idx);
25         if (onlyA(a1) && onlyA(a2) && a1 == a2 && s.find("AT") != string::npos) {
26             int at_idx = s.find("AT");
27             string b = s.substr(p_idx + 1, at_idx - p_idx - 1);
28             string ca = s.substr(at_idx + 2);
29             string c = ca.substr(0, ca.size() - a2.size());
30             if (isCorrect(a1 + "P" + b + "T" + c))
31                 return true;
32         }
33         else {
34             return false;
35         }
36     }
37     return false;
38 }
39
40 int main() {
41     int n;
42     cin >> n;
43     string *s = new string[n];
44     for (int i = 0; i < n; i++)
45         cin >> s[i];
46     for (int i = 0; i < n; i++) {
47         if (isCorrect(s[i]))
48             cout << "YES" << endl;
49         else
50             cout << "NO" << endl;
51     }
52     return 0;
53 }

后来查看网上解析,总结题意发现:

  1. 基本情况是 xPATx,x 只含有 ‘A‘ 或为空。这里我们用 a、b、c 表示原题中相应位置  ‘A‘ 的数量,则初始情况下,a = c,b = 1。
  2. 由条件(3),‘P‘ 和 ‘T‘ 中间每增加 1 个 ‘A‘,即 b + 1 后,整个字符串结尾要添加 1 个 ‘P‘ 前的字符串,即 c 变为 c + a。
    由初始状态 b = 1,且若 b = b + 1,则 c = c + a,可知 c = a × b

挖掘到这个深层信息,改写 isCorrect() 函数如下,效率会更高。

// C style
bool isCorrect(string s) {
    int a = 0, b = 0, c = 0;
    bool hasP = false, hasAT = false;
    for (int i = 0; i < s.size(); i++) {
        if (!hasP) {
            if (s[i] == ‘A‘) {
                a++;
                continue;
            }
            else if (s[i] == ‘P‘) {
                hasP = true;
                continue;
            }
            else {
                return false;
            }
        }
        else {
            if (!hasAT) {
                if (s[i] == ‘A‘) {
                    b++;
                    continue;
                }
                else if (s[i] == ‘T‘ && s[i - 1] == ‘A‘) {
                    hasAT = true;
                    continue;
                }
                else {
                    return false;
                }
            }
            else {
                if (s[i] == ‘A‘) {
                    c++;
                    continue;
                }
                else {
                    return false;
                }
            }
        }
    }
    if (hasP && hasAT && a * b == c)
        return true;
    else
        return false;
}

// C++ style
bool isCorrect(string s) {
    int idxP = s.find("P"), idxAT = s.find("AT");
    if (idxP != string::npos && idxAT != string::npos) {
        for (int i = 0; i < idxP; i++) {
            if (s[i] != ‘A‘)
                return false;
        }
        for (int i = idxP + 1; i < idxAT; i++) {
            if (s[i] != ‘A‘)
                return false;
        }
        for (int i = idxAT + 2; i < s.size(); i++) {
            if (s[i] != ‘A‘)
                return false;
        }
        // a * b == c
        if (idxP * (idxAT - idxP) == (s.size() - idxAT - 2))
            return true;
    }
    return false;
}

原文地址:https://www.cnblogs.com/wayne793377164/p/8806902.html

时间: 2024-11-11 17:00:08

【PAT】我要通过!的相关文章

PAT 1009 说反话 C语言

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格. 输出格式:每个测试用例的输出占一行,输出倒序后的句子. 输入样例: Hello World Here I Come 输出样例: Come I Here World Hello 1 #include<stdio.h> 2 #

PAT 1006 换个格式输出 C语言

让我们用字母B来表示"百".字母S表示"十",用"12...n"来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数.例如234应该被输出为BBSSS1234,因为它有2个"百".3个"十".以及个位的4. 输入格式:每个测试输入包含1个测试用例,给出正整数n(<1000). 输出格式:每个测试用例的输出占一行,用规定的格式输出n. 输入样例1: 234 输出样例1: BBSSS1

俺也晒晒pat代码!

最近在练习pat,很多题目不是很好做,一直找不到思路.通过google题目名称可以找到很多前辈的做题记录,这极大的方便了后来者.在此默默谢谢他们! 不过这同时也带了一些问题,有些前辈可能是急于出结果,所以使用了非常麻烦的方法把题目做出来了,有些后来者不经思考草草学习了就也这么做了...俺觉得这不应当是刷题所追求的目标,俺觉得既然练习旧的题目就应当追求超越前人,多想想有没有更巧妙,更简便的方法.否则科学技术也就停滞不前了... 不过俺又想了想或许很多“大牛”的确使用了简单的方法,只是他们没有时间或

pat 1068 动态规划/Fina More Conis

1068. Find More Coins (30) Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special re

PAT甲级1005 Spell It Right

题目:PAT甲级 1005 题解:水题.看到题目的第一时间就在想一位一位的mod,最后一加一转换就完事了.结果看到了N最大为10的100的次方,吓得我赶紧放弃这个想法... 发现碰到这种情况用字符串十分好用,这道题应该考察的就是这一点.大致思路就是把数字的每一位放到字符串中,然后通过ASCII码得到每一位的相加结果num,然后把num一位一位的放到stack中,使用stack是因为它先进先出的特性,最后输出就行了. 代码: 1 #include<cstdio> 2 #include<qu

PAT 团体程序设计天梯赛-练习集 题解(凑零钱,堆栈,社交集群)

开始准备cccc(cry)天梯赛了,第一周训练题,把官网挂出的训练题刷完了,对pat有了一点点的熟悉感. L1-1  就不说了... L1-2 打印沙漏 一个变量保存空格数,一个变量保存沙漏符号数,打印就行了,但这题话说wrong好几次啊,坑点是沙漏符号后面不打印空格,orz... <span style="font-size:14px;">#include<iostream> #include<stdio.h> #include<math.h

1093. Count PAT&#39;s (25)

The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3rd, the 4th, and the 6th characters. Now given any string, you are supposed to tell the numb

关于PAT和《构建之法》

这是官网的介绍——计算机程序设计能力考试(Programming Ability Test,简称PAT)旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,科学的评价计算机程序设计人才,为企业选拔人才提供参考标准.我觉得PAT的真正价值在于帮助那些学历或者专业不太好的人突破壁垒,也就是通过HR第一轮的刷简历,后面的流程还是需要自己有真才实学才可以啊.陈越姥姥致力于把PAT打造成IT业的托福,而事实上也确实如此,如今已初具规模,参加一次这样的考试,对我这种编程渣来说

2015/12/12 考了PAT,又回来玩Python了。

上次写飞机大战的坑还没填完,然后就有好长时间没有更新博客了.可能大家在疑惑我在干什么... 其实不是有意暂停博客更新的,十一月学校里有两个考试要准备,然后有好多实验要做.平时的课余时间本来就不是很多了,然后整个十一月份都在学习数据结构和算法的东西,因为报名了浙大组织的PAT考试,12月5号刚考完试.基本上就是有空的时候就是刷算法题了.. 高估了考试的难度,只报名了乙级的考试,发现自己报亏了...练习的时候这些真题基本上都能拿到满分,不过在考试的时候发现各种情况突发,还是没有自己平时的发挥..一不

A1093. Count PAT&#39;s (25)

The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3rd, the 4th, and the 6th characters. Now given any string, you are supposed to tell the numb