-
写的时候不知道怎么将字符串都转换成小写了,就弄了个循环一个个将大写转换成小写。
参考了其他文章,学到了 transform() 函数,搭配 toupper 和 tolower 就可以转换成大写或者小写。
transform(begin(sname), end(sname), begin(sname), ::tolower);
第一个第二个参数是输入容器首尾地址,第三个参数是输出容器的首地址,第四个参数是操作方式。
-
虽然前面某题看了看 map 的自定义排序,但是写了写似乎不太对。所以改成把 map 的元素先输出到向量中,然后再自定义排序函数用 sort 排序。
但最后一个测试点卡了一下,根据题目黑体标明了 “整数部分” 但当时处理的方式是累加的时候直接取整 int 这样就会舍弃小数点,导致累加的结果不对。
所以改成把整数取整再放入向量中,然后再排序。
for(auto s: sch) { s.second.score = (int)s.second.s ans.push_back(s.second); } sort(begin(ans), end(ans), cmp());
-
顺便参考别人这个代码,可以在 push_back() 用 {} 的方式来输入一个结构体。
School{s.first, (int)s.second.score, s.second.peo}
{s.first, (int)s.second.score, s.second.peo}
经测试这两种写法都是可以的,区别只是花括号前有一个结构体的类型名。
-
-
关于排序函数 cmp 这里参考 map 自定义里面说的,可以用 greater 或者 less 而这两都是结构体里面嵌套了重载函数。所以试了试结构体里面嵌套重载,然后把 cmp 放在 sort() 里面。
struct cmp { bool operator()(const School a, const School b) { if(a.score != b.score) return a.score > b.score; if(a.peo != b.peo) return a.peo < b.peo; return a.name < b.name; } };
-
关于最后同排名编号的问题,之前有一个题目处理跟这个相似 7-41 PAT排名汇总 (25 point(s)) 。
思路是记录上一个分数比较当前分数是否相同,相同继续输出上一个编号,否则更新编号。代码照着思路写一写就可以了。
-
又看了看 map 的自定义排序,应该认识到, map 基于红黑树结构,而结构决定了它排序方式是固定的。即便说 “自定义” 实际只是将原本的大到小变成小到大,不能到达 set 或者 sort 这种自定义的程度。
所以要写也就像这里,先放到 vector 然后再用 sort 自定义排序函数。
#include <bits/stdc++.h>
using namespace std;
struct School{
string name;
double score = 0;
int peo = 0;
};
struct cmp {
bool operator()(const School a, const School b) {
if(a.score != b.score) return a.score > b.score;
if(a.peo != b.peo) return a.peo < b.peo;
return a.name < b.name;
}
};
int main() {
int n;
map<string, School> sch;
cin >> n;
while(n--){
string id, sname;
int score;
cin >> id >> score >> sname;
// 不区分大小写
transform(begin(sname), end(sname), begin(sname), ::tolower);
// 输入对应学校的数据
// 判断哪个比赛
if(id[0] == 'B') {sch[sname].score += score * 1.0 / 1.5;}
if(id[0] == 'A') {sch[sname].score += score ;}
if(id[0] == 'T') {sch[sname].score += score * 1.5;}
sch[sname].peo++;
sch[sname].name = sname;
}
vector<School> ans;
for(auto s: sch)
ans.push_back(School{s.first, (int)s.second.score, s.second.peo});
sort(begin(ans), end(ans), cmp());
// 编号 保存上一个输出的分数
int i = 1, j = 1, last = -1;
cout << ans.size() << endl;
for(auto a: ans){
// 如果分数不一样则更新编号
if(last != a.score) {
j = i;
last = a.score;
}
cout << j << " " << a.name << " " << (int)a.score << " " << a.peo << endl;
i++;
}
}