Submission #391712

#TimeUsernameProblemLanguageResultExecution timeMemory
391712usachevd0Scales (IOI15_scales)C++14
100 / 100
149 ms2440 KiB
#include <bits/stdc++.h> #ifndef DEBUG #include "scales.h" #endif using namespace std; #define fi first #define se second #define mp make_pair #define pb push_back #define all(a) (a).begin(), (a).end() using ll = long long; using ull = unsigned long long; using pii = pair<int, int>; using pil = pair<int, ll>; using pli = pair<ll, int>; using pll = pair<ll, ll>; using ld = long double; template<typename T1, typename T2> bool chkmin(T1& x, T2 y) { return y < x ? (x = y, true) : false; } template<typename T1, typename T2> bool chkmax(T1& x, T2 y) { return y > x ? (x = y, true) : false; } void debug_out() { cerr << endl; } template<typename T1, typename... T2> void debug_out(T1 A, T2... B) { cerr << ' ' << A; debug_out(B...); } template<typename T> void mdebug_out(T* a, int n) { for (int i = 0; i < n; ++i) { cerr << a[i] << ' '; } cerr << endl; } #ifdef DEBUG #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #define mdebug(a, n) cerr << #a << ": ", mdebug_out(a, n) #else #define debug(...) 1337 #define mdebug(a, n) 1337 #endif template<typename T> ostream& operator << (ostream& stream, const vector<T>& v) { for (auto& x : v) { stream << x << ' '; } return stream; } template<typename T1, typename T2> ostream& operator << (ostream& stream, const pair<T1, T2>& p) { return stream << p.first << ' ' << p.second; } #ifdef DEBUG vector<int> pp; vector<int> ip; int getHeaviest(int x, int y, int z) { vector<int> ord = {x, y, z}; sort(all(ord), [&](int x, int y) -> bool { return ip[x] < ip[y]; }); return ord[2]; } int getLightest(int x, int y, int z) { vector<int> ord = {x, y, z}; sort(all(ord), [&](int x, int y) -> bool { return ip[x] < ip[y]; }); return ord[0]; } int getMedian(int x, int y, int z) { vector<int> ord = {x, y, z}; sort(all(ord), [&](int x, int y) -> bool { return ip[x] < ip[y]; }); return ord[1]; } int getNextLightest(int x, int y, int z, int w) { vector<int> ord = {x, y, z}; sort(all(ord), [&](int x, int y) -> bool { return ip[x] < ip[y]; }); int i = 0; while (i < 3 && ip[ord[i]] < ip[w]) ++i; return ord[i % 3]; } void answer(int* p) { for (int i = 0; i < 6; ++i) { assert(pp[i] == p[i]); } } #endif int pw3[10]; const int P = 720; const int Q = 120; vector<int> perm[P]; map<vector<int>, int> pid; using Mask = array<bool, P>; Mask fullMask; struct Query { int type; vector<int> args; Query() {} Query(int _type, int a, int b, int c) { type = _type; args = {a, b, c}; } Query(int _type, int a, int b, int c, int d) { type = _type; args = {a, b, c, d}; } } query[Q]; int ans[P][Q]; void prec() { vector<int> p(6); iota(all(p), 0); int ptr = 0; do { perm[ptr++] = vector<int>(all(p)); } while (next_permutation(all(p))); assert(ptr == P); ptr = 0; for (int a = 0; a < 6; ++a) { for (int b = a + 1; b < 6; ++b) { for (int c = b + 1; c < 6; ++c) { for (int type = 0; type <= 2; ++type) { query[ptr++] = Query(type, a, b, c); } for (int d = 0; d < 6; ++d) { if (d != a && d != b && d != c) { query[ptr++] = Query(3, a, b, c, d); } } } } } assert(ptr == Q); for (int pi = 0; pi < P; ++pi) { auto& p = perm[pi]; vector<int> where(6); for (int i = 0; i < 6; ++i) { where[p[i]] = i; } for (int qi = 0; qi < Q; ++qi) { auto& q = query[qi]; vector<pii> ord; for (int i = 0; i < 3; ++i) { ord.emplace_back(q.args[i], i); } sort(all(ord), [&](pii x, pii y) -> bool { return where[x.fi] < where[y.fi]; }); switch (q.type) { case 0: ans[pi][qi] = ord[2].se; break; case 1: ans[pi][qi] = ord[0].se; break; case 2: ans[pi][qi] = ord[1].se; break; case 3: int d = q.args[3]; int i = 0; while (i < 3 && where[ord[i].fi] < where[d]) ++i; ans[pi][qi] = ord[i % 3].se; break; } } } pw3[0] = 1; for (int i = 1; i < 10; ++i) pw3[i] = pw3[i - 1] * 3; fill(all(fullMask), 1); } int Count(const Mask& mask) { return count(all(mask), 1); } map<pair<Mask, int>, bool> mem; map<pair<Mask, int>, int> whatq; bool brute(Mask mask, int rem = 6) { pair<Mask, int> key = {mask, rem}; int cnt = Count(mask); if (cnt <= 1) { return mem[key] = true; } if (mem.count(key)) { return mem[key]; } if (cnt > pw3[rem]) { return mem[key] = false; } for (int qi = 0; qi < Q; ++qi) { Mask nxt[3]; for (int i = 0; i < 3; ++i) { fill(all(nxt[i]), 0); } for (int pi = 0; pi < P; ++pi) { if (mask[pi]) { nxt[ans[pi][qi]][pi] = 1; } } if (max(Count(nxt[0]), max(Count(nxt[1]), Count(nxt[2]))) <= pw3[rem - 1] && brute(nxt[0], rem - 1) && brute(nxt[1], rem - 1) && brute(nxt[2], rem - 1)) { whatq[key] = qi; return mem[key] = true; } } return mem[key] = false; } void init(int T) { prec(); brute(fullMask, 6); } int ask(int qi) { auto& q = query[qi]; switch (q.type) { case 0: return find(all(q.args), getHeaviest(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1) - 1) - q.args.begin(); break; case 1: return find(all(q.args), getLightest(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1) - 1) - q.args.begin(); break; case 2: return find(all(q.args), getMedian(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1) - 1) - q.args.begin(); break; case 3: return find(all(q.args), getNextLightest(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1, q.args[3] + 1) - 1) - q.args.begin(); break; } } void orderCoins() { Mask mask = fullMask; for (int rem = 6; rem > 0; --rem) { int qi = whatq[{mask, rem}]; int r = ask(qi); for (int pi = 0; pi < P; ++pi) { mask[pi] &= ans[pi][qi] == r; } } int pi = 0; while (pi < P && !mask[pi]) ++pi; int p[6]; for (int i = 0; i < 6; ++i) { p[i] = perm[pi][i] + 1; } answer(p); } #ifdef DEBUG int32_t main() { #ifdef DEBUG freopen("in", "r", stdin); #endif ios::sync_with_stdio(0); cin.tie(0); pp.resize(6); ip.resize(6); iota(all(pp), 0); init(-1); do { //debug(pp); for (int i = 0; i < 6; ++i) ip[pp[i]] = i; orderCoins(); } while (next_permutation(all(pp))); return 0; } #endif

Compilation message (stderr)

scales.cpp: In function 'void prec()':
scales.cpp:152:11: warning: declaration of 'p' shadows a previous local [-Wshadow]
  152 |     auto& p = perm[pi];
      |           ^
scales.cpp:126:15: note: shadowed declaration is here
  126 |   vector<int> p(6);
      |               ^
scales.cpp: In function 'int Count(const Mask&)':
scales.cpp:193:15: warning: conversion from 'std::iterator_traits<const bool*>::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  193 |   return count(all(mask), 1);
      |          ~~~~~^~~~~~~~~~~~~~
scales.cpp: In function 'void init(int)':
scales.cpp:230:15: warning: unused parameter 'T' [-Wunused-parameter]
  230 | void init(int T) {
      |           ~~~~^
scales.cpp: In function 'int ask(int)':
scales.cpp:239:94: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  239 |       return find(all(q.args), getHeaviest(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1) - 1) - q.args.begin();
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
scales.cpp:242:94: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  242 |       return find(all(q.args), getLightest(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1) - 1) - q.args.begin();
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
scales.cpp:245:92: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  245 |       return find(all(q.args), getMedian(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1) - 1) - q.args.begin();
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
scales.cpp:248:113: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
  248 |       return find(all(q.args), getNextLightest(q.args[0] + 1, q.args[1] + 1, q.args[2] + 1, q.args[3] + 1) - 1) - q.args.begin();
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
scales.cpp:251:1: warning: control reaches end of non-void function [-Wreturn-type]
  251 | }
      | ^
#Verdict Execution timeMemoryGrader output
Fetching results...