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];
}
投稿日時:
最終更新: