仍然为C++
PAT1003 我要通过! (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
解题思路
这道题一开始把我搞晕了,看了一下样例,发现2,3是需要结合在一起去理解的,所以字符串中“P”“T”只能出现一次且两者之间一定要有“A”。
但当时还没搞懂a,b,c的关系,于是去百度了一下,知道了根据规律可以总结出:a*b=c,但好像没找到怎么推导,自己试了试也没成功,暂时只能先写着了。
设置一个标志位,将各个情况排除,此题情况较多,推荐记录一下排除情况(记得排除没有p/a/t的情况),记录p,t位置,用来计算A是否符合以上结论。
中间我使用了strlen(),此函数在<cstring>头文件中。(而不是<string>)
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
int n;
char pat[101];
cin >> n;
while (n--) {
cin >> pat;
// cout << pat << endl;
int flag = true, num_P = 0, num_T = 0;
int pos_P, pos_T, len = strlen(pat);
for (int j = 0; j < len; j++) {
// cout << pat[j] << endl;
//先排除出现其他字母的情况
if (pat[j] != 'P' && pat[j] != 'A' && pat[j] != 'T') {
flag = false;
// cout << "flag1 = " << flag << endl;
break;
}
if (pat[j] == 'P') {
num_P++;
pos_P = j;
//排除出现两次及以上P
if (num_P > 2) {
flag = false;
// cout << "flag2 = " << flag << endl;
break;
}
}
if (pat[j] == 'T') {
num_T++;
pos_T = j;
//排除出现两次及以上T
if (num_T > 2) {
flag = false;
// cout << "flag3 = " << flag << endl;
break;
}
}
}
//P,A,T必须存在
if (pos_T - pos_P == 1 || num_P == 0 || num_T == 0) {
// cout<<"flag5 = "<<flag<<endl;
flag = false;
}
//判断a*b=c
if (flag) {
if ((pos_P * (pos_T - pos_P - 1)) == (strlen(pat) - pos_T - 1))
{
flag = true;
}
else {
flag = false;
}
// cout << "flag4 = " << flag << endl;
}
//根据标志位判断输出
if (flag) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
return 0;
}
PAT1004 成绩排名 (20 分)
读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:
每个测试输入包含 1 个测试用例,格式为
第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
... ... ...
第 n+1 行:第 n 个学生的姓名 学号 成绩
其中姓名
和学号
均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。
输入样例:
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
输出样例:
Mike CS991301
Joe Math990112
解题思路
当时的我首先想到了对象,且题目时间空间足够,于是就这样写了(之后感觉自己有点作死)。
反复调试后,程序可以通过前两组数据,第三组显示段错误,捣鼓好久没搞懂,网上还没有用对象写的orz,又返回看了一遍题目,发现没说学生个数小于10(我原来Student数组大小为11),然后改为101,成功ac
代码
#include <iostream>
#include <string>
using namespace std;
//建议学生对象
class Student{
public:
string name;
string sno;
int grade;
void input()
{
cin>>name>>sno>>grade;
}
void display()
{
cout<<name<<" "<<sno<<endl;
}
};
int main()
{
int n,max = 0,min = 0;
Student s[101];
cin>>n;
//输入学生信息
for(int i = 0;i < n;i++){
s[i].input();
}
//找到成绩最大和最小
for(int j = 0;j < n;j++){
if(s[max].grade < s[j].grade){
max = j;
}
if(s[min].grade > s[j].grade){
min = j;
}
}
//显示
s[max].display();
s[min].display();
return 0;
}