这道题是PAT乙级#1003题
这道题困惑了我好久,也让我真正认识到这种OJ题其实更大程度上考验的是数学能力,相比之下,代码能力反而只是一种实现的工具
先来看一下题目

题目描述

“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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

解题历程:

可以看出来这其实就是让我们判断一个字符串是否满足要求的题目,一开始我并没有在意,所以上来就写了一个循环去读取这个字符串,然后调用一个方法去根据给出的正确调节来检验这个字符串,但是在写检验方法的时候我却遇到了问题。
需要的情况似乎太多了
但是我依然没有醒悟,觉得毕竟有三个检验条件,还是用代数的检验形式,情况必然很多,所以我硬着头皮写下去,好不容易写完了,一提交,全错了!
这似乎有点问题
我看着自己写的将近一百行的检验方法,陷入了沉思。
似乎不太对,但是又说不上来,总感觉,不应该这么写,盯着看了好久,又找不出规律,就这样扔在这放了两三天,依然没有头绪,没办法了,索性去看看别人的解法吧。

他人解法:

如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
拿上面的那几个正确的举例子,那么正确的有这些:
PAT —— 对于 aPbTc 来说ac是空,b是A。所以 PAAT 是正确的。同理PAAAAAT中间加多少个A都是正确哒~
APATA —— 对于aPbTc来说,abc都是A。所以 APAATAA 是正确的。再类推一下,那么 APAAATAAA 是正确的。
AAPATAA —— 对于aPbTc来说,a和c是AA,b是A。所以AAPAATAAAA是正确的,再类推一下,AAPAAATAAAAAA 是正确的~
所以说规律就是,可以在P和T中间加A并且在T后面加A,要求必须是,中间加上一个A,末尾就得加上几倍的(P前面A的那个字符串)。换句话说就是,中间的A的个数如果是3,那么末尾的A的个数就得是开头A的个数的3倍。很巧,当中间A为一个的时候,末尾和开头A的个数必须相等正好是第二条的要求~~~
所以一句话总结字符串的要求:只能有一个P一个T,中间末尾和开头可以随便插入A。但是必须满足开头的A的个数 * 中间的A的个数 = 结尾的A的个数,而且P和T之间不能没有A~

说了不少,似乎说明白了什么规律,而且最后也给出了正确的检验方法。
但我总觉得,这像是小学的找规律题,或者说,没有给出严格的数学思路,只是列出了各种可能性后从中归纳出了规律,而不是通过推理演绎所得到的结果。
但是网上找到的所有题解都是引用了这个思路,我觉得这并不好,我需要一个更加严格,更具有逻辑性的思路
当然我这个一开始都做不出来的菜逼自然不能批评别人的思路,但是我的确看的云里雾里,只是知道了前后字符串有规律而已,所以我决定,沿着这个思路尝试着找到证明的方法


演绎法

可能归功于我喜欢看福尔摩斯,所以对演绎法也有点了解,这给了我很大的帮助,接下来就是严格的演绎证明
首先对于第一条,没什么可说的,就是要求字符串中只能有'P','A','T'三种字符。

对于第二条,要求格式为xPATx其中x可以是空字符串或者仅由字母A构成的字符串,
也就是x可以是0或任意个A,而且PAT前后均是x,即前后的字符串是相同的

然后我们再来看第三条,这才是这个题目的大头部分
如果aPbTc是正确的,那么aPbATca也是正确的,a,b,c均或者是空字符串,或者仅由字母A构成的字符串。

我们细细的品一下,开始第一句

如果 aPbTc 是正确的

很明显,他的正确性并不确定,这就说明,这种格式下的字符串要通过前两条的检验
而后一句

那么 aPbATca 也是正确的

这句话说明,这种格式下的字符串的正确性取决于上一个格式的正确性
至此我们可以看出来,第三条检验条件是完全依附于前两条的。
那么我们来看是如何依附的
对于aPbTc,如果他是正确,那么那就要满足xPATx的形式,首先我们可以很明显的看出来a,c要求相同且为空或者仅由A构成,b要求为A,此时a,c的要求基本可以忽略,但对于b来说

  1. 如果b取空,则构成aPTc的形式,即使a,c满足要求,整个字符串也不符合第二条的形式
  2. 如果b取两个及以上的A构成的字符串,同理也不满足第二条

这时可能就有人问了,前面的解法里不是说中间可以有多个A吗?别急,接着看

我们假设所有的a,c均满足要求,毕竟他们的要求很简单,而且他们也不是重点
经过上述的步骤我们发现,只有在b取A的时候才能满足aPbTc是正确的
即:

b = “A” :aPbTc正确

第一个式子的正确要求找到了,我们接着看,下一个式子为

aPbATca

这个格式正确性是取决于前一个格式的,现在我们找到了前一个格式的正确要求,那么就可以推出这个格式的正确性要求

b =“A” : aPbATca正确(不要忘了我们已经假设a,c均正确了)

此时我们可以发现,这个格式同样还是要求b = "A"而已
但是因为中间填了一个固定的A,所以P,T中间就有了两个A
同时仍要满足a,c正确,这就意味着这个格式下,后面的A的个数变成了前面的A个数的两倍,很明显嘛,前面是a,而后面是caa= c;这都是我们前面证明出来的,不满足这些要求是不可能正确的。
看起来似乎第三个要求也找到了?
别急,我们刚刚得出的结论是
aPAATca是正确的
这里我把b的位置换成了A,因为在刚才的证明中就发现了b一定是A(b=“A”)
我们再看一下第三条

如果 aPbTc 是正确的,那么 aPbATca 也是正确的

此时
aPAATca是正确的=>aPbTc是正确的,b = "AA",a = a ,c = ca
有没有发现什么,第三条可以基于自身二次成立!!!
为了更直观一点我们换成下面的写法

a1Pb1Tc1是正确的,则a1Pb1ATc1a1是正确的
首次证明时,我们直到一定要满足b1="A"的形式
此时a1Pb1ATc1a1所对应的a1PAATc1a1正确,即:
a1PAATc1a1 是正确 => a2Pb2Tc2是正确的,b2=b1+“A” a2=a1,c2=c1a1
此时中间有了两个A,a不变,b变成了两个A,c变成了之前的两倍!

再来一次?
对于a2Pb2Tc2正确,其所对应的a2Pb2ATc2a2,即a2PAAATc2a2也是正确的
因此
a2PAAATc2a2正确 => a3Pb3Tc3正确 ,b3=“AAA” a3=a2=a1 ,c3=c2a2
而c2=c1a1,所以c3 = c1a1a2,a始终不变
现在b3 变成了三个A,c3是原来的三倍

很明显之后都是这样循环自证,每次循环都会让中间的A多一个,后面的A多一倍,前面的A不变,而最开始后面的A的基数是和前面的A的个数相同,因此就变成了下面这样
第N次循环时,后面的A的个数是前面的A的个数的N倍,同时中间的A的个数是N
看起来就像是后面的A的个数是前面的A的个数乘以中间的A的个数,但其实上面这个才是真正的规律

如果中间A的个数和循环次数N不是线性关系,那规律性解法就完全失效了,但是我的演绎法依然可以找到正确的思路,毕竟找规律终归是在找巧合,而不是严格的逻辑推理。

现在我们就得出来正确的格式:

  1. 仅由P,A,T三个字母构成
  2. 满足P,T中间必须有A,且T之后的A的个数是P之前的A的个数乘以中间的A的个数

啥,你说我这个不还是跟别人的一样?你不废话,这道题难道会有两种判断格式嘛?

举个例子,如果我这样改一下

如果 aPbTc 是正确的,那么 aPb2Tca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串,其中b2表示A的个数变为原本的平方
你可劲找规律去吧,看你啥时候能想到下面这个规律

后面的的A的个数等于前面的A的个数乘以中间的A的个数的平方根

十七张牌你能秒我??

代码实现

此处引用了柳婼大神的代码,我只是加了一点注释
代码来源点这里

#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;//记录P字符出现位置if (s[j] == 'T') t = j;//记录T字符出现位置}/*要求1. 必须有 P T2. A 的个数不能为零3. 不能出现其他字符,即只能有三种字符4. P T 之间必须有A5. 前面的A乘以中间的A等于后面的A*/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");elseprintf("NO\n");}return 0;
}

(PAT)BasiclLevel_c++ #1003 我要通过!(演绎法)相关推荐

  1. PAT甲级1003 Emergency:[C++题解]dijkstra求最短路、最短路条数

    文章目录 题目分析 题目链接 题目分析 分析:求单源最短路,使用dijkstra()算法. 最短路的条数,和最短路中 人数最多的一条,输出最多人数. 本题点比较少,使用邻接矩阵d[N][N]来存. a ...

  2. PAT乙级——1003

    PAT乙1003 题目: 我要通过!(20 分) 题目分析 代码实现 题目: 我要通过!(20 分) "答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的&quo ...

  3. PAT乙级 1003 我要通过! (20分)

    PAT乙级练习总结 PAT乙级 1003 我要通过! (20分) 第二版有注释,希望我的思路可以帮助你. 文章目录 PAT乙级练习总结 一.1003题目 二.第一版只过了三个点 三.第二版 1003 ...

  4. PAT甲级 1003 Emergency

    PAT甲级 1003 Emergency As an emergency rescue team leader of a city, you are given a special map of yo ...

  5. PAT乙级 1003

    1003 我要通过!(20)(20 分)提问 "答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于PAT的"答案正确"大派送 -- 只要读入的字符串满足下 ...

  6. PAT乙级1003我要通过!

    1003 我要通过! (20分) "答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 -- 只要读入的字符串满足下列条件, ...

  7. PAT 甲级 1003

    PAT 1003 题目介绍: 给出城市的连接状况和每个城市的救援队伍的数量.给定起点和终点,求出起点到终点最短路径的个数,以及找出一条可以包含救援队最多的最短路径,输出最多可以累计的救援队的数目. 题 ...

  8. PAT(甲级) 1003. Emergency

    1003 . Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emer ...

  9. (迪杰斯特拉)Dijkstra算法详解 PAT甲级 1003

    1.迪杰斯特拉(Dijkstra)算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最 短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想) ...

最新文章

  1. ios nil、NULL和NSNull 的使用
  2. HTML 自学笔记(HTML框架+表单设计)
  3. hibernate lazy加载
  4. VTK:Utilities之TimerLog
  5. ssrs报表服务器数据库配置文件,创建报表服务器数据库(SSRS 配置管理器)
  6. 数量场的等值面与矢量场的矢量线的一些基本的东西(写得不好)
  7. MacBookPro制作Windows 11 U盘启动盘
  8. wikisql 数据集解释_【wiki维基百科中文数据集】抽取wiki数据集——实操
  9. 计算机网络里的DHCP是什么,路由器的DHCP是什么意思?有什么作用
  10. 问题解决之 Win10下 word 文件和 ppt 文件打开时遇到错误
  11. 2021年12月西电大二Python期末小总结
  12. bestsort 开通公众号了~欢迎关注哟~
  13. 前端css实现左侧盒子宽度固定,右侧宽度自适应布局
  14. 有关JIT你需要知道的
  15. github(desktop)使用教程(三) 【保姆级】{desktop tutorial repository,创建分支,编辑文件,保存修改,commit,publish to github}
  16. 大数据分析-考试复习
  17. 华师大 OJ 3055
  18. 为什么ctrl+shift+方向键不管用了_为什么你的祛痘产品不管用?
  19. qq企业邮箱 pop3服务器是什么意思,腾讯QQ企业邮箱POP3/SMTP设置
  20. NdkDemo开发从环境搭建到入门提高

热门文章

  1. 结绳中文编程入门手册
  2. 自动杀死yarn 中运行的程序
  3. 什么是进修编程言语之前
  4. linux rpm安装包忽视所有依赖强制安装
  5. Ubuntu系统重装Ubuntu系统
  6. 洛谷2336 BZOJ2754 SCOI2012 喵星球上的点名 SA 莫队 二分
  7. 怎么下载电脑自带的office版本
  8. iphone11信号强度测试软件,信号差的bug过不去了?来看看iPhone 12 Pro的实际信号测试...
  9. 三角函数π/2转化_高中数学:三角函数知识点
  10. Web 2.0时代RSS的.Net实现