这道题实际上就是模拟题,一点点按照题意写,我刚开始写了下面的代码,我觉得已经把所有情况考虑进去了:
//只能包含PAT,不能包含其他字母
//PAT中间不能没有字母,有字母且只能是1个A或多个A
//'P''T'不能重复出现
#include<bits/stdc++.h>
using namespace std;
int flag;
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i++)
{
flag = 0;
int l = 0, r = 0;
int cntP = 0, cntT = 0;
string s; cin >> s;
for (int j = 0; j < s.size(); j++)
{
//如果出现了'P' 'A' 'T'以外的字符,那么就是不合法的
if (s[j] != 'P' && s[j] != 'A' && s[j] != 'T')flag = 1;
//找'P' 'T'两个端点
if (s[j] == 'P')l = j, cntP++;
if (s[j] == 'T')r = j, cntT++;
}
//判断一下是不是有重复的‘p’ 'T'
if (cntP > 1 || cntT > 1)flag = 1;
//如果'P' 'T'中间没有A 非法
if (r - l == 1)flag = 1;
//如果'P' 'T'中间不是'A' 非法
for (int k = l + 1; k < r; k++)
{
if (s[k] != 'A')flag = 1;
}
if (!flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
但是第八个例子输出了‘YES’,正确答案是'No:
第八个例子是这个:
这个地方错误的原因是有一个规律我没有发现:
因此我们需要判断一下'P'前面'A'的个数 * 'P' 'T'中间的'A'的个数是否等于'T'之后的'A'的个数,不相等就是非法情况:
//只能包含PAT
//可以是xxPATxxx的形式
#include<bits/stdc++.h>
using namespace std;
int flag;
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i++)
{
flag = 0;
int l = 0, r = 0;
int cntP = 0, cntT = 0,cntlA = 0, cntrA = 0,cntmidA=0;
string s; cin >> s;
for (int j = 0; j < s.size(); j++)
{
//如果出现了'P' 'A' 'T'以外的字符,那么就是不合法的
if (s[j] != 'P' && s[j] != 'A' && s[j] != 'T')flag = 1;
//找'P' 'T'两个端点
if (s[j] == 'P')l = j, cntP++;
if (s[j] == 'T')r = j, cntT++;
}
//判断一下是不是有重复的‘p’ 'T'
if (cntP > 1 || cntT > 1)flag = 1;
//如果中间没有A 非法
if (r - l == 1)flag = 1;
//确定两个点之间是不是有‘A’
for (int k = l + 1; k < r; k++)
{
if (s[k] != 'A')flag = 1;
}
//统计'P'之间'A'的个数
for (int z = 0; z < l; z++)if (s[z] == 'A')cntlA++;
//统计'P''T'之间的'A'的个数
for (int z = r + 1; z < s.size(); z++)if (s[z] == 'A')cntrA++;
//统计'T'之后'A'的个数
for (int z = l + 1; z < r; z++)if (s[z] == 'A')cntmidA++;
//判断一下'P'前面'A'的个数 * 'P' 'T'中间的'A'的个数是否等于'T'之后的'A'的个数
if (cntlA*cntmidA != cntrA)flag = 1;
if (!flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}