Official

B - Find Permutation 2 Editorial by sounansya


この問題は 順列全探索 を用いることで解くことができます。

\(P\) の候補は \((1,2,\ldots,N)\) の並び替え \(N!\) 通りなので、それらを全て試し、 \(2\) つ目の条件を満たすか確かめていけば良いです。

\(1\) つでも条件を満たす \(P\) が見つかれば直ちに出力しプログラムを停止させ、全て調べた後も見つからなければ No を出力すれば良いです。

\(A_i \neq -1\) ならば \(P_i=A_i\)」という命題は「\(A_i=-1\) または \(A_i=P_i\)」というように言い換えることができるので、実装上は後者を用いると良いです。

実装例(Python3)

from itertools import permutations

n = int(input())
a = list(map(int, input().split()))
for p in permutations([i + 1 for i in range(n)]):
    ok = True
    for i in range(n):
        ok &= a[i] == -1 or p[i] == a[i]
    if ok:
        print("Yes")
        print(*p)
        break
else:
    print("No")

実装例(C++)

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n;
	cin >> n;
	vector<int> a(n);
	for (int &i : a)
		cin >> i;
	vector<int> p(n);
	iota(p.begin(), p.end(), 1);
	do {
		bool ok = true;
		for (int i = 0; i < n; i++) {
			ok &= a[i] == -1 || p[i] == a[i];
		}
		if (ok) {
			cout << "Yes" << endl;
			for (int i = 0; i < n; i++) {
				cout << p[i] << " \n"[i + 1 == n];
			}
			return 0;
		}
	} while (next_permutation(p.begin(), p.end()));
	cout << "No" << endl;
	return 0;
}

posted:
last update: