CF19A World Football Cup 题解
Content
有 \(n\) 个球队参加一场足球比赛,比赛排名前 \(\dfrac{n}{2}\) 的队伍将会进入下一轮的淘汰赛。比赛将会打 \(\dfrac{n(n-1)}{2}\) 场,胜者得 \(3\) 分,负者得 \(0\) 分,平局双方各得 \(1\) 分。排行榜上首先会按球队的积分从大到小排序,如果积分相同将会比较净胜球数(胜场比另一方领先的球数的总和减去负场比另一方落后的球数的总和的值),如果净胜球数相同会比较进球数,如果进球数还相同则会比较字典序。试求出能够晋级淘汰赛的 \(\dfrac{n}{2}\) 个队伍。
数据范围:\(1\leqslant n\leqslant 50\),球队名不超过 \(30\) 个字符,单场双方的进球数都不会超过 \(100\)。另根据 CF 官网给出的数据可得,\(n\) 保证是偶数。
Solution
看啥做啥的模拟题。
我们可以通过 \(\texttt{map}\) 直接映射得到球队名所属的球队的积分、胜场比另一方领先的球数的总和、负场比另一方落后的球数的总和、进球数。然后按照如上的关键字次序排序,便可以得到前 \(\dfrac{n}{2}\) 名的球队。
Code
int n;
string s[57], win[57];
map<string, int> q, goal, wingoal, losegoal;
struct team {
string name;
int score, wingoals, goals;
bool operator < (const team& dxy) const {
if(score != dxy.score) return score > dxy.score;
else if(wingoals != dxy.wingoals) return wingoals > dxy.wingoals;
else if(goals != dxy.goals) return goals > dxy.goals;
return name < dxy.name;
}
}teams[57];
int main() {
getint(n);
_for(i, 1, n) cin >> s[i];
_for(i, 1, n * (n - 1) / 2) {
string a, team1 = "", team2 = ""; int x, y;
cin >> a; scanf("%d:%d", &x, &y);
int len = a.size(), flag = 1;
_for(j, 0, len - 1) {
if(a[j] == '-') flag++;
else if(flag == 1) team1 += a[j];
else if(flag == 2) team2 += a[j];
}
goal[team1] += x, goal[team2] += y;
if(x > y) q[team1] += 3, wingoal[team1] += (x - y), losegoal[team2] += (x - y);
else if(x == y) q[team1] += 1, q[team2] += 1;
else q[team2] += 3, wingoal[team2] += (y - x), losegoal[team1] += (y - x);
}
_for(i, 1, n)
teams[i] = (team){s[i], q[s[i]], wingoal[s[i]] - losegoal[s[i]], goal[s[i]]};
sort(teams + 1, teams + n + 1);
_for(i, 1, n / 2) win[i] = teams[i].name;
sort(win + 1, win + n / 2 + 1);
_for(i, 1, n / 2) cout << win[i] << endl;
return 0;
}