Official

B - Ranking with Ties Editorial by yuto1115

解説

\(2\) 種類の解法を説明します。

解法 1: 問題文の通りに実装する

問題文で説明されている順位決めのプロセスをそのままプログラムとして実装する方針です。以下のような要素を実装する必要があります:

  • ある条件が満たされるまで特定の操作を繰り返す:繰り返し処理 (for 文、while 文など) を用いることで実現できます。
  • 順位が未確定である人の中での得点の最大値を求める:\(N\) 人の人それぞれについて順位が既に確定したかを配列によって管理した上で、繰り返し処理を用いることで実現できます。

解法 2: 言い換えを利用する

問題文で説明されている順位決めの方法は一見複雑でよく分からないもののように思われますが、実は以下のようなシンプルな形に言い換えることができます。

  • \(i\) の順位は、人 \(i\) よりも真に得点が高い人の数に \(1\) を足したものである。

この言い換えを利用すると、問題文で説明されているプロセスをそのままプログラムとして表現するよりも実装が簡単になります。

一般的に、この問題のように何か複雑なプロセスを導入している問題に出会った時は、そのプロセスが実際にどのように進行するのかを具体例などを用いてよく観察し、何か簡単な言い換えがないか探してみるのも良いでしょう。(もちろん、簡単な言い換えが常に存在するとは限りません。)

解法 1, 2 それぞれにおける実装例 (C++, Python) を下に掲載しています。参考にしてください。

実装例 1 (C++) :

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        cin >> p[i];
    }
    vector<int> rank(n);
    int r = 1;
    while (true) {
        int x = 0;
        for (int i = 0; i < n; i++) {
            if (rank[i]) continue;
            x = max(x, p[i]);
        }
        if (!x) break;
        int k = 0;
        for (int i = 0; i < n; i++) {
            if (p[i] == x) {
                rank[i] = r;
                k++;
            }
        }
        r += k;
    }
    for (int i = 0; i < n; i++) {
        cout << rank[i] << '\n';
    }
}

実装例 1 (Python) :

n = int(input())
p = list(map(int, input().split()))
rank = [0 for i in range(n)]
r = 1
while True:
  x = 0
  for i in range(n):
    if rank[i] != 0:
      continue
    x = max(x, p[i])
  if x == 0:
    break
  k = 0
  for i in range(n):
    if p[i] == x:
      rank[i] = r
      k += 1
  r += k

for i in range(n):
  print(rank[i])

実装例 2 (C++) :

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        cin >> p[i];
    }
    for (int i = 0; i < n; i++) {
        int rank = 1;
        for (int j = 0; j < n; j++) {
            if (p[j] > p[i]) rank++;
        }
        cout << rank << '\n';
    }
}

実装例 2 (Python) :

n = int(input())
p = list(map(int, input().split()))
for i in range(n):
  rank = 1
  for j in range(n):
    if p[j] > p[i]:
      rank += 1
  print(rank)

posted:
last update: