1085. PAT单位排行 (25)

本文介绍了一个C++程序设计实例,该实例用于解决PAT单位排名问题。通过对输入数据进行处理,包括成绩加权、单位名称标准化等步骤,最终实现对单位进行有效排名并输出排名结果。代码中使用了结构体、映射、向量等标准模板库组件。

1085. PAT单位排行 (25)
1141. PAT Ranking of Institutions (25)

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int rank;
    string school;
    int tws,ns;
    node(int r,string s,int t,int n):rank(r),school(s),tws(t),ns(n){}
};
map<string,pair<int,double>> mp;
double cptscore(char x,double score)
{
    if(x=='B') score/=1.5;
    if(x=='T') score*=1.5;
    return score;
}
void lr(char school[],int len)
{
    for(int i=0;i<len;++i){
        if(isupper(school[i])){
            school[i]=tolower(school[i]);
        }
    }
}
bool cmp(const node &a,const node &b)
{
    if(a.tws!=b.tws)
        return a.tws>b.tws;
    return a.ns==b.ns?a.school<b.school:a.ns<b.ns;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;++i){
        char id[12],school[12];
        double score;
        scanf("%s %lf %s",id,&score,school);
        score=cptscore(id[0],score);
        lr(school,strlen(school));
        auto &res=mp[school];
        res.first++;
        res.second+=score;
    }
    vector<node> v;
    for(auto &x:mp){
        string school=x.first;
        int ns=x.second.first,tws=x.second.second;
        v.push_back(node(0,school,tws,ns));
    }
    sort(v.begin(),v.end(),cmp);
    int l=v.size();
    v[0].rank=1;
    for(int i=1;i<l;++i){
        v[i].rank=(v[i].tws==v[i-1].tws)?v[i-1].rank:i+1;
    }
    printf("%d\n",l);
    for(node &x:v){
        printf("%d %s %d %d\n",x.rank,x.school.c_str(),x.tws,x.ns);
    }
    return 0;
}
<think>好的,我需要解决用户关于PAT 1085题目中测试点5的问题。首先,我需要回顾题目要求和常见的测试点问题。 根据引用[2],PAT常考的排名方式是同分布排名,即相同分数的单位应并列,后续排名跳过。例如,如果有两个单位并列第一,下一个单位应该是第三名,而不是第二。这可能与测试点5相关,因为如果排名处理不当,会导致错误。 测试点5可能涉及浮点数计算或精度问题。例如,使用浮点数计算总分时,可能存在精度丢失,导致比较出错。引用[3]提到总分的计算涉及指数运算,需要注意十进制的处理,避免累积误差。可能需要在计算时使用整数运算代替浮点数,例如将所有成绩转换为整数后再比较。 另外,单位名称的大小写是否敏感也是常见问题。题目可能要求不考虑大小写,但存储时需要统一格式,否则比较时会出错。例如,将所有单位名称转换为小写后再处理。 数据结构的选择也可能影响结果。例如,使用哈希表存储单位信息时,需要确保键的唯一性。合并不同考生成绩时,需正确累加各部分的分数,并处理可能的小数位数不一致问题。 还有可能是输出格式的问题,例如排名、单位名称、总分和考生数的对齐方式不符合要求,导致测试点失败。需要严格按照题目要求的格式输出,包括空格、顺序等。 最后,测试点5可能包含大规模数据,需要注意算法的时间复杂度。使用高效的排序算法(如快速排序)和合适的数据结构可以避免超时问题。引用[1]提到备考时需注意代码效率,这可能与此相关。</think>### PAT 1085 单位排行 测试点5 解法与注意事项 #### 1. **排名规则的正确实现** - **同分同名次**:测试点5可能考察单位总分相同但排名未正确处理的情况。例如,三个单位总分依次为 90、90、85,前两个应并列第1名,第三个应为第3名(而非第2名)。实现时需要先按总分降序排序,再遍历处理排名: ```python sorted_list = sorted(units.items(), key=lambda x: (-x[1]['total'], x[0])) rank = 1 for i in range(len(sorted_list)): if i > 0 and sorted_list[i][1]['total'] != sorted_list[i-1][1]['total']: rank = i + 1 sorted_list[i][1]['rank'] = rank ``` 参考类似排名逻辑见[^2]。 #### 2. **总分计算的精度问题** - **浮点数陷阱**:题目中总分计算公式可能涉及浮点运算(如$10^{-k}$),直接使用浮点类型可能导致精度丢失。例如,测试点5可能包含极端数据,如多次累加后误差累积。建议将分数转换为整数处理,例如: ```python # 将小数部分转为整数(假设最多有3位小数) total = integer_part * 1000 + decimal_part ``` 类似数值处理思路可参考[^3]。 #### 3. **单位名称的大小写统一** - **大小写不敏感**:题目可能要求单位名称不区分大小写(如"Pku"和"PKU"视为同一单位)。需在处理时统一转换为小写或大写: ```python school_name = input_name.strip().lower() ``` #### 4. **数据规模与性能优化** - **时间复杂度**:测试点5可能包含大量数据(如10^5条记录),需使用$O(n \log n)$的排序算法(如快速排序)。Python中建议用内置的`sorted()`函数,避免手写低效排序逻辑。 #### 5. **输出格式的严格匹配** - **字段对齐**:输出要求“排名 单位名称 总分 考生人数”时,需注意: - 单位名称按原输入输出(保留大小写) - 总分取整数部分(如计算为95.6则输出95) - 考生人数为整数 #### 示例代码片段 ```python units = {} for record in records: school = record['school'].lower() score = int(record['score'] * 1000) # 转为整数避免浮点误差 if school not in units: units[school] = {'total': 0, 'count': 0, 'name': record['school']} units[school]['total'] += score units[school]['count'] += 1 # 转换为实际总分(例如原公式为 total = A + B/1000) for school in units: units[school]['total'] = units[school]['total'] // 1000 # 取整数部分 sorted_list = sorted(units.values(), key=lambda x: (-x['total'], x['name'])) # 处理排名 current_rank = 1 for i, unit in enumerate(sorted_list): if i > 0 and unit['total'] != sorted_list[i-1]['total']: current_rank = i + 1 unit['rank'] = current_rank # 输出(示例) for unit in sorted_list: print(f"{unit['rank']} {unit['name']} {unit['total']} {unit['count']}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值