题目信息
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 (1) xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
(2)如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。
第 1 行给出一个正整数 n (≤10),是需要检测的字符串个数。
接下来每个字符串占一行,字符串长度不超过 100,
且不包含空格。
示例如下
10
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
APATTAA
输出格式:
每个字符串的检测结果占一行,
如果该字符串可以获得“答案正确”,
则输出 YES,否则输出 NO。
示例如下
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO
分析
首先谢谢大家对我 前两个习题解析的支持,
你们的支持就是我的动力!!!
回到题目:首先 模拟题目 听天由命 不要怪自己做不好
读题:定位题目类型为字符串模拟类型题目
额外知识补充分界线----------------------------
在计算机科学中,时间复杂性,又称时间复杂度,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。
时间复杂度分析:
还记得在第二题中点击☞PAT乙级 1002 写出这个数
我们分析了数据的范围以及运行时间
对于我们思考思路的引领作用
下面不说废话直接上干货
数据范围
n的取值最大为
10,每个字符串长度的取值最大为100
也就是说在题目数据范围的极限情况下将这10个每个长度为100的字符串进行遍历访问需要访问10*100=1000
个字符
运行时间
时间限制为400ms
即0.4s
根据Y总的数据范围和时间复杂度的分享
当时间限制为1~2秒时,
C++代码中的操作次数控制在 10^7∼10^8 为最佳。
本题中0.4s的情况下将操作次数控制在10^6以内肯定没问题
可以推得最多可遍历1000次全部的字符(1000*1000=10^6)
==》 放心使用各种循环不会出现
TLE(Time Limit Exceeded)
的情况
Q
1
:为什么要考虑最大数据
的范围以及最长
运行时间
? (答案在文末)
----------------------------额外知识分享结束线
分析
(1).条件1很好理解,但是很明显要解决条件3首先要解决条件2
即给出xPATx为正确答案的判定。
(2)完成xPATx为正确答案的判定后,由aPbTc 是正确的,写出推理 aPbATca 也是正确的表达式即可
表达式推理如下:
由aPbTc正确则推得符合 XPATx 的结构=>(b='A'且 a=c)=>aPATc
又有 aPbATca 正确(猜测:每增加一个b(即'A')则在c后加上1个字符串a)
综上 大胆推测:
由 aPbATca 正确=> aPbbATcaa正确
由 aPbbTcaa 正确=> aPbbbTcaaa正确
由 aPbbbTcaaa正确=>............
检验推测准确性
样例显示这四种情况均正确
并且符合我们的推理
条件2=>
设:'P’前字符串长度 =P_length
------ 'T’后子字符串长度=T_length
------且由题意知 P_length =T_length
正确字符串长度
= (P_length +"PAT"的长度+T_length )
=(P_length *2)+3)
条件3=>
设:A_mnum='P’到’T间’A’的数量,
------‘P前子字符串长度’=P_length,
正确字符串长度
=(P_length+‘P’到’T’的长度+(A_mnum)*P_length)
=(P_length(A_mnum+1))+‘P’到’T’的长度
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
cin>>n;
for(int i=0;i<n;i++){
//num[0]记录'P'的数量, num[1]记录'A'的数量,num[2]记录'T'的数量
int num[3]={0};
//设置两层的判定条件judge 和 judge1 以及记录字符'P' 'T'的位置
int jugde=0,judge1=0,p_idx,t_idx;
string temp;
cin>>temp;
for(int i=0;i<temp.length();i++){
if(temp[i]!='P' && temp[i]!='A' && temp[i]!='T'){
judge=1;
}else{
if(temp[i]=='P'){
p_idx=i;
num[0]++;
//保证正确的字符串有且仅有一个'P'
if(num[0]>1)judge=1;
}
else if(temp[i]=='A')num[1]++;
else if(temp[i]=='T'){
t_idx=i;
num[2]++;
//保证正确的字符串有且仅有一个'T'
if(num[2]>1)judge=1;
}
}
}
//根据上述的分析很明显我们可以根据推导的结果计算正确字符串应该有的长度
//该定义表示'P'到'T'的长度(包括'P'和'T')
int PT_length=t_idx-p_idx+1
if(!judge && (PT_length-1)>=2){
//条件2判定
if(temp.length()==(p_idx*2+3))judge1=1;
//条件3判定
else if(temp.length()==((PT_length-1)*p_idx)+PT_length)judge1=1;
}
if(judge)cout<<"NO"<<endl;
else{
if(judge1)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
return 0;
}
回答:
A
1
:
因为PAT一般会用边界数据(如本题中n=0和n=10)进行判定
这对于想拿到满分的朋友们就很不友好了,为了减少这样的失分,我们把出题人所给的数据的范围全部考虑就一定不会错!!!