3. 统计射击比赛成绩

134 阅读3分钟

题目描述

给定一个射击比赛成绩单,包含多个选手若干次射击的成绩分数,请对每个选手按其最高3个分数之和进行降序排名,输出降序排名后的选手ID序列。

条件如下

  1. 一个选手可以有多个射击成绩的分数,且次序不固定。
  2. 如果一个选手成绩少于3个,则认为选手的所有成绩无效,排名忽略该选手。
  3. 如果选手的成绩之和相等,则成绩之和相等的选手按照其ID降序排列。

输入描述

  • 输入第一行,一个整数N,表示该场比赛总共进行了N次射击,产生N个成绩分数(2<=N<=100)。
  • 输入第二行,一个长度为N整数序列,表示参与每次射击的选手ID(0<=ID<=99)。
  • 输入第三行,一个长度为N整数序列,表示参与每次射击的选手对应的成绩(0<=成绩<=100)。

输出描述

符合题设条件的降序排名后的选手ID序列。

用例

输入13
3,3,7,4,4,4,4,7,7,3,5,5,5
53,80,68,24,39,76,66,16,100,55,53,80,55
输出5,3,7,4
说明该场射击比赛进行了13次
参赛的选手为3,4,5,7
3号选手成绩:53,80,55,最高3个成绩的和为:80+55+53=188。
4号选手成绩:24,39,76,66,最高3个成绩的和为:76+66+39=181。
5号选手成绩:53,80,55,最高3个成绩的和为:80+55+53=188。
7号选手成绩:68,16,100,最高3个成绩的和为:100+68+16=184。
比较各个选手最高3个成绩的和,有3号=5号>7号>4号,由于3号和5号成绩相等且ID号5>3, 所以输出为:5,3,7,4
输入15
1,1,1,2,2,2,3,4,3,3,5,5,3,3,5
80,90,70,85,95,75,100,65,90,80,75,95,70,80,90
输出3,5,2,1
输入13
1,1,1,2,2,2,3,3,3,3,3,3,3
80,90,70,85,95,75,100,65,90,80,75,95,70
输出3,2,1

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include <sstream>

// 比较函数,用于对选手进行排序
bool compare(const std::pair<int, int>& a, const std::pair<int, int>& b) {
    if (a.second != b.second) {
        return a.second > b.second; // 按分数之和降序
    }
    return a.first > b.first; // 分数相同按ID降序
}

std::vector<int> rankShooting(std::vector<int>& ids, std::vector<int>& scores) {
    std::map<int, std::vector<int>> shooterScores;

    // 将成绩添加到对应的选手ID下
    for (size_t i = 0; i < ids.size(); ++i) {
        shooterScores[ids[i]].push_back(scores[i]);
    }

    // 计算每个选手最高的3个成绩之和,并存储在另一个map中
    std::vector<std::pair<int, int>> validShooters;
    for (auto& entry : shooterScores) {
        if (entry.second.size() >= 3) {
            std::sort(entry.second.begin(), entry.second.end(), std::greater<int>());
            int top3Sum = entry.second[0] + entry.second[1] + entry.second[2];
            validShooters.push_back({ entry.first, top3Sum });
        }
    }

    // 对有效选手按规则排序
    std::sort(validShooters.begin(), validShooters.end(), compare);

    // 提取排名后的选手ID序列
    std::vector<int> result;
    for (const auto& pair : validShooters) {
        result.push_back(pair.first);
    }

    return result;
}

int main() {
    int n;
    std::cin >> n;

    std::string line;
    std::getline(std::cin, line); // 忽略换行符

    // 读取选手ID
    std::getline(std::cin, line);
    std::vector<int> ids;
    std::stringstream ss(line);
    std::string id;
    while (std::getline(ss, id, ',')) {
        ids.push_back(stoi(id));
    }

    // 读取对应的成绩
    std::getline(std::cin, line);
    std::vector<int> scores;
    std::stringstream ss2(line);
    std::string score;
    while (std::getline(ss2, score, ',')) {
        scores.push_back(stoi(score));
    }

    // 获取排名结果并打印
    std::vector<int> result = rankShooting(ids, scores);
    for (size_t i = 0; i < result.size(); ++i) {
        if (i > 0) std::cout << ",";
        std::cout << result[i];
    }
    std::cout << std::endl;

    return 0;
}