C - Standings Editorial by Kiri8128
Python での実装例Python での実装例をいくつか紹介します。
ソートのキーを渡す方法
公式解説 と同様に、ソートのキーを渡したい場合、 Python では cmp_to_key
関数を使うことで実装できます。
from functools import cmp_to_key
def cmp(a, b):
x, y, i = a
xx, yy, ii = b
s = x * yy - y * xx
return 1 if s > 0 else -1 if s < 0 else 0
N = int(input())
X = []
for i in range(N):
a, b = map(int, input().split())
X.append((-a, a + b, i))
X.sort(key = cmp_to_key(cmp))
print(*[i + 1 for x, y, i in X])
2 つの要素を比較する cmp 関数では、比較結果を 1
、 0
、 -1
で返し、 sort 関数の key に入れる際には cmp_to_key(cmp)
とします。
AC コード PyPy 3(cmp_to_key を使用)
精度を上げて比較する方法
多倍長整数を使う方法
普通に a / (a + b)
をソートすると、浮動小数点数の精度が足りずに WA になってしまいます。
WA コード PyPy 3(浮動小数点数で比較)
Python では多倍長整数が扱えるので、十分な桁数を保持すれば良いです。例えば、 10 ** 100
を掛けて比較すると良いです。PyPy の場合タプルの比較は遅いことが知られているので、 (x, i)
の代わりに x * 10 ** 6 + i
などとして「一次元化」してソートする方法もあります。
AC コード PyPy 3(10 ** 100
を掛けて比較)
AC コード PyPy 3(10 ** 100
を掛けて比較、一次元化)
Decimal を使う方法
入力を Decimal で受け取ると浮動小数点数より精度を上げることができます。ただし Decimal は PyPy では遅くなるので TLE に注意です。
AC コード Python 3(精度 100 桁で Decimal を使用)
TLE コード PyPy 3(精度 100 桁で Decimal を使用)
\(10 ^ {18}\) 以下に埋め込む方法
\(\displaystyle \frac{a}{a+b}\) のソートは、逆数にして \(1\) を引くことで \(\displaystyle \frac{b}{a}\) のソートと等価になります。これにはいくつかの方法が知られていますが、商が \(1\) より大きいか小さいかで場合分けすることで、 \(0\le a,b \le 10^9 \) のとき、商を \(-10^{18}\) から \(10^{18}\) 程度の区間に(順序を保って)自然に埋め込むことができます。なお、途中計算で \(O(N)\) 回程度 \(10^{18}\) を超える整数を扱う必要がありますが、比較の際には \(64\) bit に収まっているので、実行時間のボトルネックにはなりづらいです。 詳細は ngtkana さんのブログ の「行列式ではなく傾きを使う方法」にまとめて頂いたので参考にしてください。
AC コード PyPy 3 (\(10^{18}\) 以下に埋め込む方法)
posted:
last update: