公式
F - 平均順位/Average Ranking 解説
by
F - 平均順位/Average Ranking 解説
by
nok0
はじめに、これまでの試合の平均順位を計算します。このときの順位がすでに目標の値以下であれば、これ以上試合を行う必要はありません。
そうでない場合を考えます。平均順位の値がもっとも小さくなるのは、新しく行う試合の結果が全て 1 位のときです。
このとき、新しく何試合行う必要があるでしょうか?
目標の平均順位が \(y\)、現在の平均順位が \(x\) だとします。追加で \(k\) 回 \(1\) 位を取ったときの平均順位は \(\frac{x \times n + k}{n+k}\) であり、これが \(y\) 以下である必要があります。この方程式を解くと、
\[\frac{x \times n + k}{n+k}\leq y\]
\[(x-y) n \leq (y-1)k \]
となるので、\((x-y)n\) を \(y-1\) で切り上げ除算することで、最小の \(k\) が求められます。
なお、これらの計算を浮動小数点型で行うのは、誤差の関係で危険です。今回の場合、値を \(1000\) 倍することで全て整数で行うことができます。
実装例(c++):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ll n;
cin >> n;
ll sum = 0;
for (int i = 1; i <= 4; i++) {
ll a;
cin >> a;
sum += a * i;
}
sum *= 1000;
string s;
cin >> s;
ll x1000 = (s[0] - '0') * 1000 + (s[2] - '0') * 100 + (s[3] - '0') * 10 +
(s[4] - '0');
ll y = x1000 * n;
if (sum <= y) {
cout << 0 << endl;
} else {
ll diff = sum - y;
ll ch = x1000 - 1000;
cout << (diff + ch - 1) / ch << endl;
}
}
投稿日時:
最終更新: