题解:CF200C Football Championship

· · 题解

一道大模拟

首先我们先理解题意。有一场小组赛,已经知道了前 5 组的比分,求需要多少分使得 BERLAND 赢得前二。

首先,我们肯定要计算出当前 4 个队伍的分数和 BERLAND 需要跟哪一个国家打。易得未打比赛的队伍在前 5 场比赛只有 1 次出现。

有一点难的是读入。但我们仔细观察,就会发现 goal1goal20\sim9 的正整数。由此可得 goal1goal2 都是单个字符。所以我们可以读入字符,冒号单独读入,就能算出 goal1goal2 了!(用快读也可以啦)

我们建造一个结构体,存下名字、出现次数、分数、赢球、输球。按照题目要求读入比分后,找到 BERLAND 的对手。

记最终得分为 X:Y。按照题目要求,X > Y。因为前面的得分不大,最终答案也不大。所以我们枚举差值和对手得分,用 check 函数检查答案。

check函数的实现也很简单,重新构造一个信息,更新信息,再通过题目要求排序,检查 BERLAND 是否在前二,如果是就输出答案。

代码

#include <bits/stdc++.h>
#define ps pair<string, Node>
using namespace std;

const string self = "BERLAND";//自己

struct Node {
    string name;//名字
    int k;//场数
    int score, win, lose;//得分、赢球、输球
};
map<string, Node>a;//用map存信息
string m;//self的对手

bool cmp(ps xx, ps yy) {//排序
    Node x = xx.second, y = yy.second;
    if(x.score != y.score)return x.score > y.score;//先比较得分
    if(x.win - x.lose != y.win - y.lose)return x.win - x.lose > y.win - y.lose;//比较赢球数量和输球数量的差
    if(x.win != y.win)return x.win > y.win;//比较赢球数量
    return x.name < y.name;//名字字典序
}

bool check(int x, int y) {
    map<string, Node> v = a;//更新答案
    v[self].score += 3;
    v[self].win += x, v[m].win += y;
    v[self].lose += y, v[m].lose += x;
    vector<ps>vec(v.begin(), v.end());//构造一个与信息相同的vector
    sort(vec.begin(), vec.end(), cmp);//排序
    return vec[0].first == self || vec[1].first == self;//是否在前二
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    for(int i = 1; i <= 5; i++) {
        string x, y;
        cin >> x >> y;//名字
        char p, maohao, q;
        cin >> p >> maohao >> q;//读入比分
        a[x].name = x, a[y].name = y;
        if(p == q) a[x].score += 1, a[y].score += 1;//得分相同
        else if(p > q)a[x].score += 3;//x赢
        else a[y].score += 3;//y赢
        a[x].k++, a[y].k++;//出现次数加1
        a[x].win += int(p - '0'), a[y].win += int(q - '0');//赢球
        a[y].lose += int(p - '0'), a[x].lose += int(q - '0');//输球
    }
    for(auto &p : a) {//遍历每一个国家,检查BERLAND的对手
        Node now = p.second;
        if(p.first != self && now.k < 3) {//一定不等于BERLAND
            m = p.first;break;
        }
    }
    int ansx = -1, ansy = -1;
    for(int d = 1; d <= 200; d++) {//枚举差值
        for(int y = 0; y <= 200; y++)//枚举对手得分
            if(check(y + d, y)) {//检查得分
                ansx = y + d, ansy = y;//满足条件
                goto end;
            }
    }
end:
    if(~ansx)cout << ansx << ":" << ansy;
    else cout << "IMPOSSIBLE";
    return 0;
}