1085 PAT单位排行 (25 point(s)) (测试点五)

  • 写的时候不知道怎么将字符串都转换成小写了,就弄了个循环一个个将大写转换成小写。

    参考了其他文章,学到了 transform() 函数,搭配 toupper 和 tolower 就可以转换成大写或者小写。

    transform(begin(sname), end(sname), begin(sname), ::tolower);

    第一个第二个参数是输入容器首尾地址,第三个参数是输出容器的首地址,第四个参数是操作方式。

    c++ string 字符大小写的转换

  • 虽然前面某题看了看 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 自定义排序函数。

    C++:map自定义排序

#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++;
	}
}
上一篇:2021-09-29 反射习题


下一篇:Oracle merge into 用法详解