1003. 我要通过!(20)
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
输入样例:8 PAT PAAT AAPATAA AAPAATAAAA xPATx PT Whatever APAAATAA输出样例:
YES YES YES YES NO NO NO NO
这个我真的是被整晕了的,先把不完整的代码贴上来,请忽略我,我只是放在这里,过一会儿再来看,因为现在实在是太晕了。如有高人指点,不胜感激!菜鸟真的是伤不起啊
//1h 第一版本(想看正确答案者,请忽略我)
int main()
{
int n;
cin >> n;
vector<string> strings;
for (int i = 0; i < n; i++)
{
string input_s;
cin >> input_s;
strings.push_back(input_s);
}
for (int j = 0; j < strings.size(); j++)
{
string each_string = strings[j];
string::iterator iters;
int k = 0;
int p=0,t=0;
for (iters = each_string.begin(); iters != each_string.end(); iters++)
{
char each_char = *iters;
if (each_char == 'P')
{
p = k;
}
if (each_char == 'T')
{
t = k;
}
k++;
}
if ((p != 0) && (t != (k - 1)))
{
int pp = 0;
for (int m = 0; m < p; m++)
{
if (each_string.at(m) == 'A')
{
pp++;
}
}
int tt = 0;
for (int n = p + 1; n < t; n++)
{
if (each_string.at(n) == 'A')
{
tt++;
}
}
int hh = 0;
for (int h = t + 1; h < k; h++)
{
if (each_string.at(h) == 'A')
{
hh++;
}
}
if ((pp == p) && (tt == (t - p - 1)) && (hh = k - t - 1))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
else
{
if ((p == 0) && (t == (k - 1)))
{
int xx=0;
for (int x = 1; x < t; x++)
{
if (each_string.at(x) == 'A')
{
xx++;
}
}
if (xx == (t - 1))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
}
}
return 0;
}
第二版本代码,只能得六分。可能还是我没有找到合适的算法去解这道题!先坚持不看答案,自己再想!
#include<vector>
#include <sstream>
#include<cmath>
#include<iomanip>
#include<iostream>
#include <ctype.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
bool IsAllA(string a, int m, int n)//判断数组a中,m到n位置的元素是否全为A
{
bool temp = true;
for (int i = m; i <= n; i++)
{
if (a[i] != 'A')
{
temp = false;
}
}
return temp;
}
int main()
{
int n;
cin >> n;
string str[10];
bool state = 0;
vector<string> rightstrs;
for (int i = 0; i < n; i++)
{
cin >> str[i];
}
for (int i = 0; i < n; i++)
{
string s = str[i];
if (s[0] == 'P')//判断第一个元素是否为P
{
if (s[s.length() - 1] == 'T')//判断最后一位是否为T
{
//判断中间的元素是否全为A
if (s.length() == 2)
{
state = false;
}
else
{
state = IsAllA(s, 1, s.length() - 2);
}
if (state == true)
{
rightstrs.push_back(s);
}
}
else
{
state = false;
}
}
else if (s[0]=='A')
{
int pl = s.find('P');//找到第一个P出现的位置
int tl = s.find('T');//找到T的位置
if ((IsAllA(s, 1, pl - 1))&&(pl>0)&&(tl>0))//首A到首P全是A,且PT都存在
{
if (((tl - pl) == 2) && (s[tl - 1] == 'A'))//判断P和T中间是否只有一个A元素
{
state = IsAllA(s, tl + 1, s.length() - 1);
if (state == true)
{
rightstrs.push_back(s);
}
}
else if ((IsAllA(s,pl+1,tl-1))&&(IsAllA(s,tl+1,s.length()-1)))//判断PT中间不止一个A的情况,但满足PT两边全是A
{
string a = s.substr(0,pl);
string b = s.substr(pl + 2, tl-pl-2);
string ca = s.substr(tl+1,s.length()-1-tl);
string c;
for (int x = 0; x < (ca.length() - a.length()); x++)
{
c += "A";
}
string temp = a + "P" + b + "T" + c;
for (int y = 0; y < rightstrs.size(); y++)
{
if (temp == rightstrs[y])
{
state = true;
break;
}
}
}
else
{
state = false;
}
}
else
{
state = false;
}
}
else
{
state = false;
}
if (state==1)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
第三版本答案,17分,不知什么临界点没考虑到
#include<vector>
#include <sstream>
#include<cmath>
#include<iomanip>
#include<iostream>
#include <ctype.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
bool IsAllA(string a, int m, int n)//判断数组a中,m到n位置的元素是否全为A
{
bool temp = true;
for (int i = m; i <= n; i++)
{
if (a[i] != 'A')
{
temp = false;
}
}
return temp;
}
bool IfCheck(string s)
{
int count = 0;
for (int i = 0; i < s.length(); i++)
{
if ((s[i] == 'A') || (s[i] == 'P') || (s[i] == 'T'))
{
count++;
}
}
if (count == s.length())
{
return true;
}
else
{
return false;
}
}
int main()
{
int n;
cin >> n;
string str[10];
vector<string> rightstrs;
for (int i = 0; i < n; i++)
{
cin >> str[i];
}
for (int i = 0; i < n; i++)
{
string s = str[i];
int slen = s.length();
bool state = 0;
if (IfCheck(s))
{
int pl = s.find('P');
int tl = s.find('T');
int al = s.find('A');
if ((pl >= 0) && (tl >= 0) && (al >= 0))//如果三种元素都存在
{
if (pl == 0) //第一个元素是否为P
{
if (tl == (slen - 1))//最后元素是否为T
{
if (s=="PAT")
{
state = true;
rightstrs.push_back(s);
}
else if (IsAllA(s, 1, slen - 2))//中间元素全是A
{
string temp = "P" + s.substr(2,slen-2);
for (int j = 0; j < rightstrs.size(); j++)
{
if (temp == rightstrs[j])
{
state = true;
rightstrs.push_back(s);
}
}
}
}
}
else if (al==0)//第一个元素为A的情况
{
if (((tl - pl) == 2) && (s[pl + 1] == 'A'))//中间含有PAT,判断两边A的个数是否相同
{
int cnta1 = pl;
int cnta2 = slen - 1 - tl;
if ((cnta1 == cnta2) && (IsAllA(s, 0, pl - 1)) && (IsAllA(s, tl+1, slen - 1)))//注意判断是否全是A
{
state = true;
rightstrs.push_back(s);
}
}
else
{
string a = s.substr(0, pl);//这里是通过aPbATca 组合原本的aPbTc,然后判断它是否在原来的正确字符串集合中出现过
string b = s.substr(pl + 2, tl-pl-2);
string ca = s.substr(tl+1,slen-1-tl);
string c;
if ((a != "") && (b != "") && (ca != ""))
{
for (int x = 0; x < (ca.length() - a.length()); x++)
{
c += "A";
}
if (IsAllA(a, 0, a.length() - 1) && IsAllA(b, 0, b.length() - 1) && IsAllA(c, 0, c.length() - 1))
{
string temp = a + "P" + b + "T" + c;
for (int y = 0; y < rightstrs.size(); y++)
{
if (temp == rightstrs[y])
{
state = true;
rightstrs.push_back(s);
break;
}
}
}
}
}
}
}
}
if (state==1)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
第四版本的代码,18分,自己都被自己进步的速度惊呆了,不过不要放弃,坚持就是胜利!!!!(先放在这里,改天再来继续做)
#include<vector>
#include <sstream>
#include<cmath>
#include<iomanip>
#include<iostream>
#include <ctype.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
bool IsAllA(string a)
{
bool state = true;
for (int i = 0; i < a.length(); i++)
{
if (a[i] != 'A')
{
state = false;
break;
}
}
return state;
}
bool IfDealed(string s)
{
int num = 0;
for (int i = 0; i < s.length(); i++)
{
if ((s[i] == 'P') || (s[i] == 'A') || (s[i] == 'T'))
{
num++;
}
}
if (num == s.length())
{
return true;
}
else
{
return false;
}
}
int main()
{
int n;
cin >> n;
string strs[10];
vector<string> IsTrue;
for (int i = 0; i < n; i++)
{
cin >> strs[i];
}
for (int i = 0; i < n; i++)
{
string s = strs[i];
if (IfDealed(s))
{
if (s.length() < 3)
{
cout << "NO" << endl;
}
else
{
int pl = s.find('P');
int tl = s.find('T');
//这次版本的思路是,首先判断P为首字母时的情况,只有PAT,基于条件的PAAAT才正确,其他错误
if (pl == 0)
{
if (tl == (s.length() - 1))
{
if ((tl - pl) == 2)
{
if (s[pl + 1] == 'A')
{
cout << "YES" << endl;
IsTrue.push_back(s);
}
else
{
cout << "NO" << endl;
}
}
else
{
//这种情况下也应该判断一下,字符串PT中间是否都为A
int numa = tl - pl - 1;
string temp;
for (int k = 0; k < numa - 1; k++)
{
temp += "A";
}
temp = "P" + temp + "T";
bool iftrue = false;
for (int j = 0; j < IsTrue.size(); j++)
{
if (temp == IsTrue[j])
{
iftrue = true;
IsTrue.push_back(s);
cout << "YES" << endl;
}
}
if (!iftrue)
cout << "NO" << endl;
}
}
else
{
cout << "NO" << endl;
}
}
//首字母不是P,利用aPbTc
else
{
int pa = pl;
int pta = tl - pl - 1;
int ta = s.length() - tl - 1;
if ((ta / pa) == pta)
{
string a = s.substr(0, pl);//这里是通过aPbATca 组合原本的aPbTc,然后判断它是否在原来的正确字符串集合中出现过
string b = s.substr(pl + 1, tl - pl - 2);
string c = s.substr(tl + 1, s.length() - 1 - tl);
if ((IsAllA(a)) && (IsAllA(b)) && (IsAllA(c)))
{
//感觉是这里的问题,满足上述条件,还要判断原来的aPbTc是否正确啊,有点晕
cout << "YES" << endl;
IsTrue.push_back(s);
}
else
{
cout << "NO" << endl;
}
}
else
{
cout << "NO" << endl;
}
}
}
}
else
{
cout << "NO" << endl;
}
}
return 0;
}