浙江大学软件学院 2020 年保研机考 7-3 Partial School Ranking (C++)

In a Group Programming Contest, each university is supposed to send n students who must compete independently. The universities are ranked according to the total score of their students. Your job is to generate the ranklist.

It sounds like a simple problem, but what makes it complicated is that we have lost all the teams’ information! What we have is a list of only some of the students’ scores, and some photos taken from the contest sites which shows several students with the same university badge. You just have to recover the ranklist as much as you can.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N ( ≤ 1000 ) N (≤1000) N(1000). Then N N N lines follow, each gives the infomation of a student in the format:
ID k k k t e a m m a t e 1 ⋯ t e a m m a t e k teammate_1⋯teammate_k teammate1teammatek Score
where ID is a unique 4-digit identification number for a student; k ( 0 ≤ k ≤ 5 ) k (0≤k≤5) k(0k5) is the number of teammates of this student in a photo; t e a m m a t e i teammate_i teammatei's are the ID's of his/her teammate; and Score is this student’s score which is in the range [0, 400].
It is guaranteed that each ID with a Score is given only once.

Output Specification:

For each case, first print in a line the number of universities (all the students that are related directly or indirectly as teammates are considered in the same university). Then output the partial school ranking in the format:
ID S S c o r e t o t a l Score_{total} Scoretotal
where ID is the smallest student ID in the university; S is the total number of its students; and S c o r e t o t a l Score_{total} Scoretotal is the total score that can be recovered for that university. The universities must be given in descending order of their S c o r e t o t a l Score_{total} Scoretotal, or in ascending order of S if there is a tie, or in ascending order of ID if there is still a tie.

Sample Input:

11
7456 3 7457 7458 7459 157
6666 3 5551 5552 7777 100
1234 3 5678 9012 0002 80
8888 0 340
2468 3 0001 0004 2222 110
7777 1 6666 57
3721 1 2333 30
9012 3 1236 1235 1234 10
1235 2 5678 9012 50
2222 4 1236 2468 6661 6662 16
2333 4 3721 6661 6662 6663 44

Sample Output:

4
8888 1 340
0001 15 340
5551 4 157
7456 4 157

Solution:

// Talk is cheap, show me the code
// Created by Misdirection 2021-09-19 13:27:53
// All rights reserved.

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

using namespace std;

struct School{
    int rootID;
    int nums;
    int scoreSum;

    School(int r, int num, int s){
        rootID = r;
        nums = num;
        scoreSum = s;
    }
    ~School(){}
};

unordered_map<int, int> scores;
unordered_map<int, bool> valid;
unordered_map<int, int> position;
unordered_map<int, bool> vis;
int father[10005];
int n;
vector<School> schools;

int findFather(int a){
    int tmp = a;
    while(tmp != father[tmp]) tmp = father[tmp];
    return tmp;
}

void Union(int a, int b){
    int fa = findFather(a);
    int fb = findFather(b);

    if(fa < fb) father[fb] = fa;
    else father[fa] = fb;

    return;
}

bool cmp(School &a, School &b){
    if(a.scoreSum != b.scoreSum) return a.scoreSum > b.scoreSum;
    if(a.nums != b.nums) return a.nums < b.nums;
    return a.rootID < b.rootID;
}

int main(){
    
    scanf("%d", &n);
    for(int i = 0; i < 10005; ++i) father[i] = i;

    int id, k, score;
    for(int i = 0; i < n; ++i){
        scanf("%d %d", &id, &k);
        valid[id] = true;

        for(int j = 0; j < k; ++j){
            int tmp;
            scanf("%d", &tmp);
            valid[tmp] = true;
            Union(id, tmp);
        }

        scanf("%d", &score);
        scores[id] = score;
    }

    for(int i = 0; i < 10000; ++i){
        if(!valid[i]) continue;

        int r = findFather(i);
        if(!vis[r]){
            vis[r] = true;
            position[r] = schools.size();

            schools.emplace_back(r, 1, scores[i]);
        }
        else{
            int pos = position[r];

            schools[pos].nums++;
            schools[pos].scoreSum += scores[i];
        }
    }


    sort(schools.begin(), schools.end(), cmp);
    printf("%d\n", schools.size());
    for(int i = 0; i < schools.size(); ++ i) 
        printf("%04d %d %d\n", schools[i].rootID, schools[i].nums, schools[i].scoreSum);


    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

负反馈循环

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值