一个域名可以做中英文两个网站吗/seo网站推广费用
发表在专栏“PAT乙级题目详解”,并在持续更新中。
https://blog.csdn.net/column/details/23947.html
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;\
- 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;\
- 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
分析:
看到这个题目,首先是从“A”“P”“T”的位置和数量分析,
1.假设left表示“P”的数量,显然“P”的数量有且只有一个;P的前面应该是没有或者仅有“A”;
2.mid表示中间的“A”的数量,mid的数量也要大于等于1;
3.right表示“T”的数量,right的数量应该为1.right的前面是“P”和“A”,并且“P”和“T”之间至少有一个“A”(即mid == 1)。
#include <iostream>
#include <string>
using namespace std;int main()
{int n;cin >> n;string test;int l = 0;//输入的字符串的长度for (int i = 0; i < n; i++){int left = 0;//记录左边的"P"出现的次数int mid = 0;//记录中间的"A"出现的次数int right = 0;//记录右边的"T"出现的次数//输入一个字符串,判断cin >> test;l = test.size();//遍历字符串中的每一个字母for (int j = 0; j < l; j++){如果出现了非法字符,直接输出“NO”,并结束if (test[j] != 'P' && test[j] != 'A' && test[j] != 'T' && test[j] != ' '){//cout << "NO" << endl;break;}//如果当前字符是"A",则继续循环,知道找到"P"if (test[j] == 'A'){if (left == 1){mid++;}continue;}//如果当前字符是"P",if (test[j] == 'P'){left++;continue;}//如果当前字符是"T"if (test[j] == 'T'){if (mid >= 1){right++;}continue;}}if (left == 1 && right == 1 && mid >= 1){cout << "YES" << endl;}else{cout << "NO" << endl;}}system("pause");return 0;
}
这种思路只能通过前面的7个测试,“APAAATAA”这种情况不通过。
仔细想一下,应该“如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。”这句话的问题。
(1)这句话说的是任意满足条件的aPbTc正确,则可以得到另外一个正确的表达式aPbATca。
(2)那么最简单的正确的表达式是PAT(b的初始值是A),可以得到PAAT也是正确的,延伸出PAAAT正确。
(3)在第(2)条是在“a”和“c”为空的情况下得到的,那么在“a”“c”赋值的情况下,假设“a” “c”都为“A”,那么“APATA”是正确的,可以得到“APAATAA”也是正确的,延伸出“APAAATAAA”也是正确的,到这,是不是发现了一些规律呢?还没有发现吗,好吧,再来看
(4)“a”赋值“A”c赋值“AA”(这样设置的原因是在第(3)条中“a”和“c”设置的是一样的,所以在本条中希望设置的不一样,以体现规律的适用性),最简单的是“APAATAA”,可以得到“APAAATAAA”.可能有人会疑问为什么在“a”赋值“A”c赋值“AA”的情况下,最简单的不是“APATAA”呢?因为如果把它写成“aPbATca”形式,找不到一个“aPbTc”形式来验证它的正确性。
(5)得出结论,每一次的延伸,b都是多了一个“A”,同时“ca”也是“a”的翻倍,所以可以得到结论a*b = c,符合这个条件的就是对的,不符合就是错的。
(6)原来这个题目看起来这么难,分析到最后,仅仅是一个找规律的题目而已啊。生活中有很多看似很难的事情,多尝试一下,同样可以成功的!!!
好了,不多说了,附代码:
#include <iostream>
#include <string>
using namespace std;int main()
{int n;cin >> n;string test;int l = 0;//输入的字符串的长度for (int i = 0; i < n; i++){int left = 0;//记录左边的"A"出现的次数int mid = 0;//记录中间的"A"出现的次数int right = 0;//记录右边的"A"出现的次数int t = 0;//记录T出现的次数int p = 0;//记录P出现的次数//输入一个字符串,判断cin >> test;l = test.size();//遍历字符串中的每一个字母for (int i = 0; i < l; i++){如果出现了非法字符,结束//if (test[j] != 'P' && test[j] != 'A' && test[j] != 'T' && test[j] != ' ')//{// //cout << "NO" << endl;// break;//}//计算"P"之前的"A"的数目,之前一定要没有出现过"P"if (test[i] == 'A' && p == 0 && t == 0){left++;continue;}//计算"P"的数目,if (test[i] == 'P'){p++;continue;}//计算中间的"A"的数目,之前一定要出现一个"P",并且只能出现这一个if (test[i] == 'A' && p == 1 && t == 0){mid++;continue;}//计算"T"的数目,"T"之前必定要出现"A"if (test[i] == 'T' && mid >= 1){t++;continue;}//计算后面的"A"的数目,之前一定要出现一个"T"if (test[i] == 'A' && p == 1 && t == 1){right++;continue;}else{break;}}//结束并判断//if (p == 1 && t == 1 && left * mid == right){cout << "YES" << endl;}else{cout << "NO" << endl;}}system("pause");return 0;
}