题目内容:
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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
分析:
条件一:P,A,T三个大写字母一个都不能少;除了这三个字母不能出现其他的字符
条件二:PAT,这种形式的字符串,如果左右两边字符相等,则直接获得正确,但其他形式的你不能直接说错,需要进入第三条件进一步判断。
条件三:如果X正确,则Y也正确,其中注意X是一个自变量,因此Y是一个因变量,什么意思呢,这就是告诉我们如果aPbTc是正确的,想要正确b无法为空,且a==c。
假设b等于“A”,ac是必须相等的,则aPATa,符合条件二,那么aPAATaa是正确的
aPAATaa是正确的, 那么aPAAATaaa也是正确的
aPAAATaaa是正确的, 那么aPAAAATaaaa也是正确的
aPAAAATaaaa是正确的, 那么aPAAAAATaaaaa也是正确的…
依次类推,我们发现PT中间A的数量决定后面字符串a的数量
条件三容易犯一个错误,看见aPbTc正确就代入条件二得出b=A,然后得出aPAATaa,这种格式是正确的,而忘记后面这条一旦正确就会进入下一个迭代,触发aPAAATaaa也正确,导致答案少了而只有部分正确
Talk is cheap,Show me the code:
【方案一:2019/09/27】 正则表达式解决:
/// <summary>
/// PAT Basic Level 1003
/// </summary>
class P1003
{
public void Judge()
{
string targets = "PAT";
int n = Convert.ToInt32(Console.ReadLine());
string[] inputStr= new string[9];
for (int i = 0; i < n; i++)
{
inputStr[i] = Console.ReadLine();
}
for (int i = 0; i < n; i++)
{
bool flag = false;
#region 条件一判断,不可行为NO,可行则进入条件二 先判断是否有其他字符,再判断是否缺少PAT中某个字符
for (int j = 0; j < inputStr[i].Length; j++) //判断每一条字符串里面的所有字符是否含有其他字符
{
if (targets.Contains(inputStr[i][j])) continue;
else flag = true; break;
}
if (flag)
{
inputStr[i] = "NO";
continue;
}
//判断每一条字符串里面是否缺少PAT中的任意一个字符
bool b = inputStr[i].Contains('P') && inputStr[i].Contains('A') && inputStr[i].Contains('T');
if (!b) { inputStr[i] = "NO"; continue; }
#endregion
#region 条件二判断,不可行进入条件三,可行则YES 先检查是否存在xPATx这种格式再验证前后字符串是否相等
string rex2 = @"^(A*?)PAT(A*?)$";
string re2 = @"^(A*?)PAT(A*?)$";
Regex rgx2 = new Regex(re2);
Match result2 = rgx2.Match(inputStr[i]);
bool pass21 = Regex.IsMatch(inputStr[i],rex2);
//Console.WriteLine(result[0].Value+" "+result[1].Value); //这里的字符应该是xP和Tx 需要删除P和T再来比较
string s21 = result2.Groups[1].ToString();
string s22 = result2.Groups[2].ToString();
bool pass22 = s21.Equals(s22);
if (pass21&&pass22) //如果这里符合条件二的话则离开当前循环进入下一循环不进入第三条件
{
inputStr[i] = "YES";
continue;
}
#endregion
//说明:aPbTc是正确的,即符合xPATx这种格式 所以a==c,b=A
//那么原来的条件就是 xPAATxx是正确的
//接下来不断地的顺推即可,但我用正则不管你规律如何
//先看形式对不对,再验证T后面的a是否是P前a的n倍(n等于中间A个数)
#region 条件三判断,不可行直接NO,可行则YES
string rex3 = @"^(A*?)PA*?T(A*?)$";
string re3 = @"^(A*?)P(A*?)T(A*?)$";
Regex rgx3 = new Regex(re3);
Match result3 = rgx3.Match(inputStr[i]) ;
bool pass31 = Regex.IsMatch(inputStr[i], rex3);
//int c3 = result3[].Value.Length;
int mid = result3.Groups[2].Length;
string s31 = result3.Groups[1].ToString();
string s32 = result3.Groups[3].ToString();
string s = "";
for (int k = 0; k < mid; k++)
{
s += s31;
}
bool pass32 = (s32==s);
if (pass31 && pass32)
{
inputStr[i] = "YES";
continue;
}
else inputStr[i] = "NO";
#endregion
}
for (int i = 0; i < n; i++)
{
Console.WriteLine(inputStr[i]);
}
//foreach (string s in inputStr)
//{
// Console.WriteLine(s);
//}
Console.ReadKey();
}
}
在PAT提交时如果出现非零返回的错误提示,那需要考虑的多半是程序的异常了
- 方案二
- 方案三