公式

C - Standings 解説 by en_translator


Let us first design a function that compares the success rates of two people. Here, it is discouraged to compare \(\frac{A_i}{A_i+B_i}\) and \(\frac{A_j}{A_j+B_j}\) using a floating-point number type, due to potential computational errors. In fact, some test cases are prepared to hack the solutions that compares values using std::double.

In this problem, we can clear the fractions of \(\frac{A_i}{A_i+B_i}<\frac{A_j}{A_j+B_j}\) to get \({A_i}{(A_j+B_j)}<{A_j}{(A_i+B_i)}\), which enables us to compare on an integer type. (Note that \({A_i}{(A_j+B_j)}\) does not fit in a 32-bit integer type, so we need to use a 64-bit integer type instead.)

All that left is to pass the function designed above to a sorting function in the standard library. But there is one more caveat here: the standard library std::sort is not the stable sort (Wikipedia). This means that if the comparison results in a tie, the original order might be swapped.

To handle this issue, use the stable-sort function std::stable_sort, or tweak the comparison function so that it checks if \(i<j\) when \({A_i}{(A_j+B_j)}={A_j}{(A_i+B_i)}\).

Sample code (C++):

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<pair<int, int>> ab;
    for(int i = 0; i < n; i++) {
        int a, b;
        cin >> a >> b;
        ab.emplace_back(a, a + b);
    }
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    auto f = [&](int i, int j) {
        auto [ai, aj] = ab[i];
        auto [bi, bj] = ab[j];
        return (long long)ai * bj > (long long)aj * bi;
    };
    stable_sort(p.begin(), p.end(), f);
    for(int i = 0; i < n; i++) cout << p[i] + 1 << " \n"[i == n - 1];
}

投稿日時:
最終更新: