1003 我要通过! (20 分)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符; - 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串; - 如果
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. 条件1:只能是P A T 这三种字符,不能有其他类别字符
2. 条件2: xPATx(x为空或x为A),就是正确的,注意这里PAT前后要一样,都是x嘛。
3.条件3:
aPbTc要是正确,就暂定为b必须是A,a和c相等,要么为A,要么为空。即aPATa(a为空或A).则aPbATca 即aPAATaa(a为空或A)是正确的,aPAATaa是正确的,那么这里b=AA,a = a,c=aa,那么aPAAATaaa是正确的,aPAAATaaa是正确的,那么b=AAA,a=a,c=aaa,那么aPAAAATaaaa是正确的(a为空或A),以此推.....。这里的规律为要么是PAAAAA....T(有>=1个A),或者aPAAAA...Taaaa...,也就是中间A的个数等于T后面A = a * 这个个数。
综上,要正确,就要满足以下条件:
1. 仅有PAT三种字符,P和T有且仅有一个
2. A至少1个,至少的情况是PAT(a为空),中间的A是有约束的,即locationT - locationP - 1>=1,即locationT - locationP>=2。
3.条件3中类似aPAAAATaaaa,中间的A的个数 = T后面的的个数/P前面a的个数。
条件2中xPATx(要么为空PAT,要么为A->A..PATA..)
其实这两种情况都可以放在一起,locationP(P前面A的个数)*(locationT - locationP -1)(中间A的个数) = str.size() - locationT - 1) (T后面A的个数)
同时满足上面3个条件就是正确的,否则就是错误的。
代码:
#include <iostream>
using namespace std;
#include <string>
bool inPAT(char str)//A
{
if (str != 'P' && str != 'A' && str != 'T')
return false;
return true;
}
bool judge(string str)
{
int i;
int locationP, locationT,countP = 0, countT = 0;
for (i = 0; i < str.size(); i++)
{
if (!inPAT(str[i])) return false;
if (str[i] == 'P') { locationP = i; countP++; }
if (str[i] == 'T') { locationT = i; countT++; }
}
if (countP != 1 || countT != 1 || (locationT - locationP < 2) ||
(locationP * (locationT - locationP -1) != str.size() - locationT - 1))
return false;
return true;
}
int main()
{
int n;
cin >> n; //这里'\n'还在输入流里面。
cin.get();
string *instance = new string[n + 1];
for (int i = 0; i < n; i++)
{
getline(cin, instance[i], '\n');
}
for (int i = 0; i < n; i++)
{
if (judge(instance[i]))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
我第一次做的代码,是利用题目浅层意思做的
#include <iostream>
using namespace std;
#include <string>
bool inPAT(char str)//A
{
if (str != 'P' && str != 'A' && str != 'T')
return false;
return true;
}
bool inA(char str)
{
if (str != 'A')
return false;
return true;
}
bool judge(string str)
{
int i,j,k;
for ( i = 0; i < str.size(); i++)
{
if (!inPAT(str[i])) return false;
if (str[i] == 'P')
{
for ( j = 0; j < i; j++) //AAPATAA
{
if(!inA(str[j])) return false;
}
for ( j = i + 1; j < str.size(); j++)
{
if (str[j] == 'T')
{
for (k = j + 1; k < str.size(); k++)
{
if (!inA(str[k])) return false;
}
if ((j - i) == 2)
{
if (str[i + 1] != 'A')
{
return false;
}
if ((i - 0) == (str.size() - j -1))
{
return true;
}
}
//PAAT
if ((j - i) >2)
{
for (k = i + 1; k < j; k++)
{
if (str[k] != 'A')
{
return false;
}
}
// PAAT / xPAATxx
int num = j - i - 1;
if ( ((i - 0)*num == (str.size() - j - 1)))
{
return true;
}
}
else
{
return false;
}
}
}
}
}
return false;
}
int main_1003()
{
int n;
cin >> n;//这里'\n'还在输入流里面。
cin.get();
string *instance = new string[n + 1];
for (int i = 0; i < n; i++)
{
getline(cin, instance[i],'\n');
}
for (int i = 0; i < n; i++)
{
if (judge(instance[i]))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
return 0;
}