PAT单位排行

PAT单位排行

1. 题目地址

    https://www.acwing.com/problem/content/1636/

2. 题目解析

    本题需要知道:多关键字排序、构造函数、unordered_map的知识。

3. 题解

    我们需要用结构体来存储学校的三个信息:
        1.  名称(用于日后输出)
        2.  加权分
        3.  人数
    在输入的时候,我们可以声明map,来将学校的名字和代表学校的结构体关联起来,边接收边处理。
    在处理的过程中,有时需要除以1.51.5包含因子3。因此,可能会有除不尽的情况。例如:总分 / 1.5 = 123.9999999。实际为124。如果直接截断,则为123,这是精度不正确导致的错误。
    因此,我们可以加上一个小的误差。这里的经验值为1e-8。这样的话,再进行截断,就不会有精度的问题了。
    处理完成后,我们再将结构体放在vector数组中。再按照多关键字进行排序。排序之后,注意处理排名的问题就可以了。
    注意:由于本题关于学校的名称是不区分大小写的。因此,在接收数据时,统一转换成小写即可。

4. 代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <vector>

using namespace std;

struct School{
    double sum;
    int cnt;
    string name;
    //定义构造函数
    School(): sum(0),cnt(0){}
    //重载小于号,进行多关键字排序
    bool operator<(School &s) const{
        if(sum != s.sum){
            return sum > s.sum;
        }
        if(cnt != s.cnt){
            return cnt < s.cnt;
        }
        return name < s.name;
    }
};

unordered_map<string,School> h;
vector<School> schools;

string to_lower(string str){
    string result = "";
    for(int i = 0; i < str.size(); i ++){
        if(str[i] >= 'A' && str[i] <= 'Z'){
            result += str[i] + 32;
        }else{
            result += str[i];
        }
    }
    return result;
}

int main(){
    int n;
    scanf("%d",&n);
    for(int i = 0; i < n; i ++){
        string id,sch;
        double score;
        cin >> id >> score >> sch;
        //计算加权总分
        if(id[0] == 'B'){
            score /= 1.5;
        }else if(id[0] == 'T'){
            score *= 1.5;
        }
        //将学校名称,统一转换成小写
        sch = to_lower(sch);
        h[sch].sum += score;
        h[sch].cnt++;
        h[sch].name = sch;
    }
    for(auto item : h){
        //加上一个非常小的数,解决精度问题
        item.second.sum = (int)(item.second.sum + 1e-8);
        //将学校(结构体)放在vector数组中
        schools.push_back(item.second);
    }
    //将学校按照多关键字排序
    sort(schools.begin(),schools.end());
    printf("%ld\n",schools.size());
    int order = 1;
    for(int i = 0; i < schools.size(); i ++){
        if(i != 0 && schools[i].sum != schools[i-1].sum){
            order = i + 1;
        }
        //输出相关信息
        printf("%d %s %d %d\n",order,schools[i].name.c_str(),(int)schools[i].sum,schools[i].cnt);
    }
    return 0;
}
posted @   夏目^_^  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示