Official

C - Round-Robin Tournament Editorial by nok0


この問題を解くには、文字列などで入力を受け取り、o の個数を数えることで勝ち数を各プレイヤーについて求め、問題文の条件に沿ってプレイヤー番号を並び替えればよいです。

ここでの実装上の課題は、プレイヤー番号の並び替えですが、例えば以下の \(3\) 種類の方針が考えられます。

  • ペア(勝ち数、プレイヤー番号)を勝ち数の降順、プレイヤー番号の昇順になるように比較関数を設計してソートする。

  • ペア(勝ち数、プレイヤー番号 \(\times -1\) )をペアの辞書順の降順にソートする。

  • 勝ち数を比較し、プレイヤー番号を std::stable_sort 等の安定ソートを用いて並び替える。(詳細は、ABC308-C 解説 等も参考にしてください)

実装例も参考にしてください。

実装例(C++, \(1\) 番目の方針):

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<pair<int, int>> win(n);
	for(int i = 0; i < n; i++) {
		string s;
		cin >> s;
		win[i] = {count(s.begin(), s.end(), 'o'), i};
	}
	auto cmp = [](pair<int, int> a, pair<int, int> b) {
		if(a.first != b.first) return a.first > b.first;
		return a.second < b.second;
	};
	sort(win.begin(), win.end(), cmp);
	vector<int> ans(n);
	for(int i = 0; i < n; i++) ans[i] = win[i].second + 1;
	for(int i = 0; i < n; i++) cout << ans[i] << " \n"[i == n - 1];
}

実装例(C++, \(2\) 番目の方針):

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<pair<int, int>> win(n);
	for(int i = 0; i < n; i++) {
		string s;
		cin >> s;
		win[i] = {count(s.begin(), s.end(), 'o'), -i};
	}
	sort(win.rbegin(), win.rend());
	vector<int> ans(n);
	for(int i = 0; i < n; i++) ans[i] = -win[i].second + 1;
	for(int i = 0; i < n; i++) cout << ans[i] << " \n"[i == n - 1];
}

実装例(C++, \(3\) 番目の方針):

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int> win(n), p(n);
	iota(p.begin(), p.end(), 0);
	for(int i = 0; i < n; i++) {
		string s;
		cin >> s;
		win[i] = count(s.begin(), s.end(), 'o');
	}
	auto cmp = [&](int i, int j) {
		return win[i] > win[j];
	};
	stable_sort(p.begin(), p.end(), cmp);
	for(int i = 0; i < n; i++) cout << p[i] + 1 << " \n"[i == n - 1];
}

posted:
last update: