Submission #1256227

#TimeUsernameProblemLanguageResultExecution timeMemory
1256227biankScales (IOI15_scales)C++20
Compilation error
0 ms0 KiB
#pragma once #include <bits/stdc++.h> using namespace std; #define forn(i, n) for (int i = 0; i < int(n); i++) #define forsn(i, s, n) for (int i = int(s); i < int(n); i++) #define dforn(i, n) for (int i = int(n) - 1; i >= 0; i--) #define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--) using vi = vector<int>; using ll = long long; using ii = pair<int, int>; #define fst first #define snd second #define all(x) begin(x), end(x) #define sz(x) int(x.size()) #define pb push_back #define eb emplace_back int getMedian(int A, int B, int C); int getHeaviest(int A, int B, int C); int getLightest(int A, int B, int C); int getNextLightest(int A, int B, int C, int D); void answer(int C[]); const int N = 6; const int M = 720; vi orders[M]; int simulate(int A, int B, int C, int D, int t, int orderIdx) { const vi &order = orders[orderIdx]; vi v = {A, B, C}; sort(all(v), [&](const int &lhs, const int &rhs) { return order[lhs] < order[rhs]; }); tie(A, B, C) = make_tuple(v[0], v[1], v[2]); if (t == 0) return B; if (t == 1) return A; if (t == 2) return C; assert(t == 3 && D != -1); if (order[A] > order[D]) return A; if (order[B] > order[D]) return B; if (order[C] > order[D]) return C; return A; } int doQuery(int A, int B, int C, int D, int t) { A++, B++, C++, D++; if (t == 0) return getMedian(A, B, C) - 1; if (t == 1) return getLightest(A, B, C) - 1; if (t == 2) return getHeaviest(A, B, C) - 1; return getNextLightest(A, B, C, D) - 1; } int pot[N + 1]; map<pair<vi, int>, bool> memo; vector<tuple<int, int, int, int, int>> all_moves; vector<vi> division(int A, int B, int C, int D, int t, vi &possibilities) { vector<vi> ret(3); for (auto p : possibilities) { int r = simulate(A, B, C, D, t, p); int id = r == C ? 2 : r == B; ret[id].pb(p); } return ret; } bool solve(vi &possibilities, int moves) { pair<vi, int> state = {possibilities, moves}; if (memo.count(state)) return memo[state]; if (sz(possibilities) <= 1) { return memo[state] = true; } if (sz(possibilities) > pot[6 - moves]) return false; vector<pair<vector<vi>, int>> options; int idx = 0; for (auto [A, B, C, D, t] : all_moves) { vector<vi> groups = division(A, B, C, D, t, possibilities); if (sz(groups[0]) == sz(possibilities) || sz(groups[1]) == sz(possibilities) || sz(groups[2]) == sz(possibilities)) { continue; } options.eb(groups, idx); idx++; } sort(all(options), [&](const auto &A, const auto &B) { auto &lhs = A.fst, &rhs = B.fst; return max({sz(lhs[0]), sz(lhs[1]), sz(lhs[2])}) < max({sz(rhs[0]), sz(rhs[1]), sz(rhs[2])}); }); for (auto [groups, i] : options) { if (solve(groups[0], moves + 1) && solve(groups[1], moves + 1) && solve(groups[2], moves + 1)) { return memo[state] = true; } } return memo[state] = false; } int first_move = 75; int second_move = 18; void init(int /*T*/) { pot[0] = 1; forn(i, N) pot[i + 1] = pot[i] * 3; vi order(N); iota(all(order), 0); int i = 0; do orders[i++] = order; while (next_permutation(all(order))); forn(A, N) forn(B, A) forn(C, B) forn(t, 3) all_moves.eb(A, B, C, -1, t); forn(D, N) forn(A, N) forn(B, A) forn(C, B) { if (A != D && B != D && C != D) { all_moves.eb(A, B, C, D, 3); } } vi possibilities(M); iota(all(possibilities), 0); auto [A, B, C, D, t] = all_moves[first_move]; vector<vi> groups = division(A, B, C, D, t, possibilities); forn(i, 3) { tie(A, B, C, D, t) = all_moves[second_move]; vector<vi> other_groups = division(A, B, C, D, t, groups[i]); forn(j, 3) solve(other_groups[j], 2); } } void doMove(vi &possibilities, int moves) { int idx = 0; for (auto [A, B, C, D, t] : all_moves) { vector<vi> groups = division(A, B, C, D, t, possibilities); if (sz(groups[0]) == sz(possibilities) || sz(groups[1]) == sz(possibilities) || sz(groups[2]) == sz(possibilities)) { continue; } if (memo[{groups[0], moves + 1}] && memo[{groups[1], moves + 1}] && memo[{groups[2], moves + 1}]) { int r = doQuery(A, B, C, D, t); int id = r == C ? 2 : r == B; possibilities = groups[id]; return; } idx++; } assert(false); } void orderCoins() { vi possibilities(M); iota(all(possibilities), 0); for (auto i : {first_move, second_move}) { auto [A, B, C, D, t] = all_moves[i]; vector<vi> groups = division(A, B, C, D, t, possibilities); int r = doQuery(A, B, C, D, t); int id = r == C ? 2 : r == B; possibilities = groups[id]; } int moves = 2; while (sz(possibilities) > 1) { pair<vi, int> state = {possibilities, moves}; assert(memo[state]); doMove(possibilities, moves); moves++; } assert(sz(possibilities) == 1); assert(moves <= 6); vi ans = orders[possibilities.back()]; int ret[N]; forn(i, N) ret[ans[i]] = i + 1; answer(ret); }

Compilation message (stderr)

scales.cpp:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
/usr/bin/ld: /tmp/ccSTwblL.o: in function `doQuery(int, int, int, int, int)':
scales.cpp:(.text+0x1526): undefined reference to `getNextLightest(int, int, int, int)'
/usr/bin/ld: scales.cpp:(.text+0x1539): undefined reference to `getMedian(int, int, int)'
/usr/bin/ld: scales.cpp:(.text+0x1549): undefined reference to `getHeaviest(int, int, int)'
/usr/bin/ld: scales.cpp:(.text+0x1559): undefined reference to `getLightest(int, int, int)'
/usr/bin/ld: /tmp/ccSTwblL.o: in function `orderCoins()':
scales.cpp:(.text+0x3e78): undefined reference to `answer(int*)'
/usr/bin/ld: /tmp/ccNe73OP.o: in function `main':
grader.c:(.text.startup+0x83): undefined reference to `init'
/usr/bin/ld: grader.c:(.text.startup+0x101): undefined reference to `orderCoins'
collect2: error: ld returned 1 exit status