PAT乙1004.成绩排名

题目

读入n名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:每个测试输入包含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

思考

如果这一题能够用python的字典来做,肯定非常简单,然而我正在练习C++。C++里面和python有点相似的是map,因此我的第一想法是用map来完成这道题。当然,由于对map的使用不熟,因此也花了一定的时间。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <map>
#include <cmath>
using namespace std;
//https://www.cnblogs.com/wswang/p/4833900.html 换行
//http://blog.csdn.net/yas12345678/article/details/52601624 map
int main(){
int n;
cin >> n;
char c = cin.get(); //读取换行符
map<int, string> m;
for(int i=0; i<n; i++){
string str;
getline(cin, str); //带空格的字符串,使用getline
string score = "";
string nameid = "";
int cnt = 0;
for(int i=0; i<str.length(); i++){
if(str[i] == ' '){
cnt++;
}
if(cnt != 2){
nameid += str[i];
}
if(cnt == 2){
if(str[i]>='0' && str[i]<='9'){
score += str[i];
}
}
}
int sum = 0; //将字符串score转为整数
for(int i=0; i<score.length(); i++){
sum += (score[i]-'0')*pow(10,score.length()-1-i);
}

m.insert(pair<int, string>(sum, nameid));
}
map<int, string>::reverse_iterator it2 = m.rbegin();
cout << it2 -> second << endl;
map<int, string>::iterator it = m.begin();
cout << it -> second << endl;
}

上面程序需要注意的有两个地方:
(1)我们在使用getline来读入带有空格的字符串时,会发现如果其前面有cin,那么getline就会读入前面的回车而停止输入,因此cin是不会处理换行符的。因此,我们需要另外就换行符进行处理,即我上面的一句:char c = cin.get(); //读取换行符
(2)还有个比较混乱的地方是,对map迭代器的使用。要记住,m.end()是不可访问的,要想访问最后一个数据,可以使用m.rbegin()。一般的迭代方式如下:

1
2
3
4
5
6
7
8
9
map<string,int> m;
map<string,int>::iterator it;
it = m.begin();
while(it != m.end())
{
//it->first;
//it->second;
it ++;
}

另外,看看别人在做此题时有什么其他简便的方法。没错啊,第一反应是结构体或者类来着,然而我忘记怎么写了,罪过啊!!!我的做法是先把所有输入存起来,之后再进行排序比较,而且还是利用了map会对key进行排序的机制;其实直接使用边输入边比较的方法会更简单。而且,也不用处理字符串了。。。我想得太复杂了,以后得多思考后再写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

struct Student{
string name;
string num;
int grade;
} temp, max_, min_;

int main(){
int n;
max_.grade = -1;
min_.grade = 101;
cin >> n;
while(n--){
cin >> temp.name >> temp.num >> temp.grade;
if(temp.grade > max_.grade) max_ = temp;
if(temp.grade < min_.grade) min_ = temp;
}
cout << max_.name << " " << max_.num << endl;
cout << min_.name << " " << min_.num << endl;
}