比赛
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <vector>
#include <ostream>
#include <sstream>
#include <unordered_map>
#include <algorithm>
#include <queue>
using namespace std;

constexpr int score_max = 10;
constexpr int top_count = 3;

struct Score {
int student_id;
int score_sum;
vector<int> scores;

explicit Score(int id) : student_id(id), score_sum(0) {
scores.resize(score_max + 1);
}

bool operator<(const Score &other) const {
if (score_sum == other.score_sum) {
for (int i = score_max; i >= 1; --i) {
if (scores[i] != other.scores[i]) {
return scores[i] < other.scores[i];
}
}
}
return score_sum < other.score_sum;
}
};

int main() {

int students;
int teachers;
char c;
std::string input_str;
getline(cin, input_str);
istringstream iss(input_str);
iss >> teachers >> c >> students;

if (students < 3 || students > 100 ||
teachers < 3 || teachers > 100) {
cout << "-1" << endl;
return 0;
}

vector<vector<int>> scores(teachers, vector<int>(students, 0));
for (int i = 0; i < teachers; ++i) {
getline(cin, input_str);
istringstream iss2(input_str);
string score_str;
int count = 0;
while (getline(iss2, score_str, ',')) {
int score = stoi(score_str);
if (score < 1 || score > 10) {
cout << "-1" << endl;
return 0;
}
scores[i][count] = score;
count++;
}
if (count != students) {
cout << "-1" << endl;
return 0;
}
}

// 计算出前三名
priority_queue<Score> top3;
for (int i = 0; i < students; ++i) {
Score score(i + 1);
for (int j = 0; j < teachers; ++j) {
auto val = scores[j][i];
score.score_sum += val;
score.scores[val]++;
}
top3.push(score);
}

// 取出前三名
int count = 0;
for (int i = 0; i < top_count; ++i) {
auto it = top3.top();
if (count == 0) {
cout << it.student_id;
} else {
cout << "," << it.student_id;
}
count++;
top3.pop();
}

return 0;
}

这道题本身并不难,结合之前的做题经验完全不在话下。

但是题目有点故意恶心人,这是 华为OD 题目的常态,你一定要注意横向是一个评委给每个同学打的分数,存值和取值的时候一定不要弄混了。

1
2
3
4
5
4,5
10,6,9,7,6
9,10,6,7,5
8,10,6,5,10
9,10,8,4,9