C - Round-Robin Tournament 解説
by
shobonvip
各プレイヤーの勝ち数として取りうる値は \(0\) 以上 \(N-1\) 以下の \(N\) 個の整数です。そこで、各整数についてバケツを用意することを考えます。
各プレイヤーは、勝ち数のバケツにプレイヤー番号を入れます。全プレイヤーが番号を入れ終わったあと、\(i=N-1, N-2, \cdots, 0\) の順に、\(i\) のバケツに含まれる番号を小さい順に出力すればよいです。
このようにしてソートする方法はバケットソートと呼ばれます。この問題の場合、ソートにかかる時間・空間計算量はともに \(O(N)\) です。
実装例(C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
// 入力を受け取る
int n;
cin >> n;
vector<string> c(n);
for (int i=0; i<n; i++){
cin >> c[i];
}
// 各人についての勝ち数を求める
vector<int> wins(n);
for (int i=0; i<n; i++){
for (int j=0; j<n; j++){
if (c[i][j] == 'o'){
wins[i] += 1;
}
}
}
// 勝ち数は, 0 以上 n-1 以下の整数しか取りえない
// bucket[i] は勝ち数 i の番号をすべて入れる
vector bucket(n, vector<int>(0));
for (int i=0; i<n; i++){
bucket[wins[i]].push_back(i);
}
// さきほど, 番号の小さい順に bucket に入れたので,
// bucket[i] の中身は, すでに番号の小さい順になっている.
// 勝ち数の多い方から, bucket[i] の中身を出力していけばよい
for (int i=n-1; i>=0; i--){
for (int j: bucket[i]){
cout << j+1 << ' ';
}
}
cout << '\n';
}
実装例(Python)
# 入力を受け取る
n = int(input())
s = [input() for i in range(n)]
# 各人についての勝ち数を求める
wins = [0] * n
for i in range(n):
for j in range(n):
if s[i][j] == 'o':
wins[i] += 1
# 勝ち数は, 0 以上 n-1 以下の整数しか取りえない
# bucket[i] は勝ち数 i の番号をすべて入れる
bucket = [[] for i in range(n)]
for i in range(n):
bucket[wins[i]].append(i)
# さきほど, 番号の小さい順に bucket に入れたので,
# bucket[i] の中身は, すでに番号の小さい順になっている.
# 勝ち数の多い方から, bucket[i] の中身を答え ans に追加する
ans = []
for i in range(n-1,-1,-1):
for j in bucket[i]:
ans.append(j+1)
# 答えを出力
print(*ans)
投稿日時:
最終更新: