1790C: Premutation ⧉
This is a simple bruteforce deduction problem. We need to deduce a permutation of elements [1, n]
for some integer n
from a set of clues. The clues are n
snapshots of the permutation where, each with a different element of the
permutation missing. These snapshots of the permutation give us two possible values for each position in the permutation. Being as each element in the permutation is only missing in one of the n
snapshots, we can use the frequencies
with which a value appears at a given position to reconstruct the permutation.
Our deduction starts by noting that we can immediately conclude the correct starting and ending elements from the permutation. In both cases, we will see the correct starting and ending elements n-1
times in the snapshots.
So, we settle that the correct first element is the value that appeared most in that position in the snapshots. That means the other value that appeared in that position must appear wherever else it appeared in the snapshots.
This will set off a chain of conclusions that will leave us to simply fill in the last element, which we know already.
_83#include <iostream>_83#include <vector>_83#include <map>_83#include <set>_83#include <functional>_83_83void solve() {_83 int n;_83 std::cin >> n;_83 std::vector<std::map<int,int>> possibilities (n);_83 std::map<int, std::set<int>> holding;_83_83 for (int i = 0; i < n; ++i) {_83 for (int pos = 0; pos < n-1; ++pos) {_83 int x;_83 std::cin >> x;_83 holding[x].insert(pos);_83 possibilities[pos][x]++;_83 }_83 }_83_83 std::vector<bool> seen (n, false);_83 std::vector<int> perm (n, -1);_83_83 std::function<void(int,int)> settle_by_deduction = [&] (int pos, int val) {_83 perm[pos] = val;_83_83 int other_val = [&] {_83 for (auto [candidate, _] : possibilities[pos]) {_83 if (candidate != val) return candidate;_83 }_83 return -1;_83 }();_83_83 if (other_val == -1) return;_83_83 int other_pos = [&] {_83 for (int other : holding[other_val]) {_83 if (other != pos) return other;_83 }_83 return -1;_83 }();_83_83 if (other_pos == -1) return;_83_83 seen[pos] = true;_83_83 if (!seen[other_pos])_83 settle_by_deduction(other_pos, other_val);_83 };_83_83 auto most_freq_at = [&] (int idx) {_83 int best = -1;_83 int val;_83_83 for (auto [candidate, cnt] : possibilities[idx]) {_83 if (cnt > best) {_83 best = cnt;_83 val = candidate;_83 }_83 }_83_83 return val;_83 };_83_83 settle_by_deduction(0, most_freq_at(0));_83 settle_by_deduction(n-1, most_freq_at(n-2));_83_83 for (int x : perm) {_83 std::cout << x << ' ';_83 }_83 std::cout << '\n';_83}_83_83_83int main() {_83 int t;_83 std::cin >> t;_83 for (int tc = 1; tc <= t; ++tc) {_83 solve();_83 }_83 return 0;_83}
If you found this solution helpful, consider leaving a star!