1 条题解

  • 0
    @ 2026-10-26 22:50:06

    思路与算法

    首次按分数降序与编号升序排序;每轮原序列的胜者和败者分别有序,给胜者加1以后线性归并,避免每轮完整排序。

    正确性说明

    胜者按原排名取子序列且都加1,故内部排序关系不变;败者不加分也维持原序。两条有序列归并后就是本轮的正确排名,由初排归纳至最后一轮。

    复杂度

    O(N log N+RN)时间、O(N)空间;这里N为单侧人数,实际人数2N,初排与两组临时数组均计入。

    易错点

    相同分数比较编号,不能按实力打破排名平局;实力只用于相邻两人对局。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    struct P {
        int id, s, w;
    };
    bool cmp(P a, P b) {
        return a.s != b.s ? a.s > b.s : a.id < b.id;
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, r, q;
        cin >> n >> r >> q;
        n *= 2;
        vector<P> a(n), tmp(n), win, lose;
        for (int i = 0; i < n; i++) {
            a[i].id = i + 1;
            cin >> a[i].s;
        }
        for (auto &p : a)
            cin >> p.w;
        sort(a.begin(), a.end(), cmp);
        while (r--) {
            win.clear();
            lose.clear();
            for (int i = 0; i < n; i += 2) {
                P x = a[i], y = a[i + 1];
                if (x.w < y.w)
                    swap(x, y);
                x.s++;
                win.push_back(x);
                lose.push_back(y);
            }
            merge(win.begin(), win.end(), lose.begin(), lose.end(), tmp.begin(), cmp);
            a.swap(tmp);
        }
        cout << a[q - 1].id << "\n";
    }
    
    • 1

    信息

    ID
    1906
    时间
    1000ms
    内存
    225MiB
    难度
    普及−
    标签
    递交数
    0
    已通过
    0
    上传者