题目链接:https://www.patest.cn/contests/pat-b-practise/1080
在B1044讲过map的简单应用,此题目主要用到了map的遍历、map的排序(可以对Value排序)。
map的key值可以是任意类型,遍历时需要用到迭代器。比如:
map<string,Student> stu; //定义一个map,包含string的学号和Student结构体
map<string,Student>::iterator it; //定义一个同类型的迭代器
it = stu.begin();
while(it != stu.end()){ /* 遍历时实现一些需求
if(it->second.g1>=200){ //it->first表示每个pair的第一个key,it->second表示第二个
if(it->second.g2>it->second.g3)
it->second.g = round(it->second.g2 * 0.4 + it->second.g3 * 0.6);
else it->second.g = it->second.g3;
} */
it++;
}
利用迭代器就能方便实现遍历。
接下来看map的排序,map默认按照key排序,如果想改变其排序方式,或者按照Value排序,则可以考虑将map转化为vector再进行排序。
将map转化为vector只需要如下两句:
typedef pair<string, Student> PAIR; //每一个点对pair,类型与map中点对一致
vector<PAIR> vs(stu.begin(), stu.end()); //声明一个vector,将一个map全部转化为vector
对vector排序需要写cmp函数,由于本题需要对pair中第二个类型Student中的平均成绩G进行排序,因此cmp可写成如下:
bool CmpByG(const PAIR& p1, const PAIR& p2) { //vector中对PAIR类型,故传入PAIR,对其第二个类型进行降序排序
if(p1.second.g > p2.second.g) return true; //p.second表示第二个类型
if(p1.second.g == p2.second.g){ //第二个相等时,再按照第一个增序排序
if(p1.first<p2.first) //string类型排序,直接比较
return true;
else return false;
}
return false;
}
排序时只需要写下如下sort函数,即可实现map的排序:
sort(vs.begin(),vs.end(),CmpByG);
了解了map的排序和遍历后,此题目就很好处理;输入时写入map中,然后对平均值排序即可得到结果。
代码如下:
#include <iostream>
#include <map>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
struct Student{
int g1,g2,g3,g;
};
map<string,Student> stu;
typedef pair<string, Student> PAIR;
bool CmpByG(const PAIR& p1, const PAIR& p2) {
if(p1.second.g > p2.second.g) return true;
if(p1.second.g == p2.second.g){
if(p1.first<p2.first)
return true;
else return false;
}
return false;
}
int main()
{
int P,M,N;
string xuehao;
cin>>P>>M>>N;
for(int i=0;i<P;i++){
cin>>xuehao;
cin>>stu[xuehao].g1;
stu[xuehao].g2 = stu[xuehao].g3 = stu[xuehao].g = -1;
}
for(int i=0;i<M;i++){
cin>>xuehao;
cin>>stu[xuehao].g2;
if(stu[xuehao].g != -1)
stu[xuehao].g1 = stu[xuehao].g3 =stu[xuehao].g =-1;
}
for(int i=0;i<N;i++){
cin>>xuehao;
cin>>stu[xuehao].g3;
if(stu[xuehao].g != -1)
stu[xuehao].g1 = stu[xuehao].g2 =stu[xuehao].g =-1;
}
map<string,Student>::iterator it;
it = stu.begin();
while(it != stu.end()){
if(it->second.g1>=200){
if(it->second.g2>it->second.g3)
it->second.g = round(it->second.g2 * 0.4 + it->second.g3 * 0.6);
else it->second.g = it->second.g3;
}
it++;
}
vector<PAIR> vs(stu.begin(), stu.end());
sort(vs.begin(),vs.end(),CmpByG);
for (int i = 0; i < vs.size(); i++) {
if(vs[i].second.g>=60)
cout << vs[i].first<<" "<< vs[i].second.g1 <<" "<< vs[i].second.g2 <<" "<< vs[i].second.g3<<" "<< vs[i].second.g << endl;
}
return 0;
}