更加体会到:在充分理解题意后,一定要选择合适的、能完整满足需求的存储结构。比如本题,一开始我是用vector<pair<string,int>> 存放信息,但越写下去 就越感到不便,只得改成用结构体数组来存放。
整体思路:按照顺序对每一个location的考生逐批次处理,对于每一location的考生,我们需要得到的是
- 学号
- location号码
- 分数
- 每个考生在此location的排名
所有批次的考生处理完毕后,再对所有的学生按照分数和学号,整体的进行一次排名,这样就可以输出了。
代码:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct info //存储信息的结构体
{
string id; //学号
int score; //得分
int trank, rank; //trank是在所有人中的分数排名,rank是在学生所在的location那小部分人中排名
int local; //location号码
info(string x, int y, int z) //构造
{
id = x;
score = y;
rank = 0;
trank = 0;
local = z;
}
};
bool cmp(info a, info b) //先按分数排名
{
return a.score > b.score;
}
bool cmp1(info a, info b) //最后的总排序,既要考虑总排名,也要考虑id号码
{
if (a.trank != b.trank) return a.trank < b.trank;
else return a.id < b.id;
}
int main()
{
int locnum, tnum = 0, tempnum; //location号码,总人数,各location的任务书
cin >> locnum;
vector<info> data; //存放所有学生的总数组
for (int i = 0; i < locnum; i++)
{
cin >> tempnum;
tnum += tempnum;
vector<info> datai; //存在当前location的局部数组
for (int j = 0; j < tempnum; j++) //存储当前location的每个学生信息
{
string idi;
int scorei;
cin >> idi >> scorei;
datai.push_back(info(idi, scorei, i + 1));
}
sort(datai.begin(), datai.end(), cmp); //按分数排序,注意 此时还没得到最终的排名,只是排个序
int stemp = -1;
for (int j = 0; j < tempnum; j++) //真正的排名
{
if (datai[j].score != stemp)
{
datai[j].rank = j + 1;
stemp = datai[j].score;
}
else
datai[j].rank = datai[j - 1].rank;
data.push_back(datai[j]); //把临时数组中的学生信息 转存到全局数组
}
}
sort(data.begin(), data.end(), cmp); //全局数组的排序
int stemp = -1;
for (int j = 0; j < tnum; j++) //获得每个考生在所有人中的排名
{
if (data[j].score != stemp)
{
data[j].trank = j + 1;
stemp = data[j].score;
}
else
data[j].trank = data[j - 1].trank;
}
sort(data.begin(), data.end(), cmp1); //按照学号 和 总排名,做最后一次排序
cout << tnum;
for (auto i : data) //输出
{
cout << endl;
cout << i.id << " " << i.trank << " " << i.local << " " << i.rank;
}
return 0;
}