PAT1003,1004

仍然为C++

PAT1003 我要通过! (20 分)

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 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

解题思路

这道题一开始把我搞晕了,看了一下样例,发现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;
}

猜你喜欢

转载自blog.csdn.net/winsumer/article/details/88586723