제출 #551692

#제출 시각아이디문제언어결과실행 시간메모리
551692elazarkoren저울 (IOI15_scales)C++17
100 / 100
202 ms1964 KiB
#include <bits/stdc++.h> #include "scales.h" #define x first #define y second #define all(v) v.begin(), v.end() #define chkmin(a, b) a = min(a, b) #define chkmax(a, b) a = max(a, b) using namespace std; typedef long long ll; typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<int, int> pii; typedef vector<pii> vii; const ll A = 9e8; const int mod = 1e9 + 9; int Hash(vi &v) { ll ans = 0; for (int x : v) { ans = (ans * A % mod + x + 1) % mod; } return ans; } map<int, vi> startegy_tree; //type 1 = light, // 2 = heavy, // 3 = med, // 4 = next vvi all_per; bool Solve(vi &permutations, int x) { if (permutations.size() <= 1) return true; int log3 = 0; int n = permutations.size(); for (int i = 1; i < n; i *= 3, log3++); if (x + log3 > 6) return false; int hash = Hash(permutations); if (startegy_tree.count(hash)) return true; for (int a = 1; a <= 6; a++) { for (int b = a + 1; b <= 6; b++) { for (int c = b + 1; c <= 6; c++) { vi v1, v2, v3; for (int y : permutations) { auto &v = all_per[y]; int ind1, ind2, ind3; for (ind1 = 0; v[ind1] != a; ind1++); for (ind2 = 0; v[ind2] != b; ind2++); for (ind3 = 0; v[ind3] != c; ind3++); int i = max({ind1, ind2, ind3}), j = min({ind1, ind2, ind3}); if (i != ind1 && j != ind1) v1.push_back(y); else if (i != ind2 && j != ind2) v2.push_back(y); else v3.push_back(y); } if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) { startegy_tree[hash] = {a, b, c, 3}; return true; } } } } for (int a = 1; a <= 6; a++) { for (int b = a + 1; b <= 6; b++) { for (int c = b + 1; c <= 6; c++) { for (int d = 1; d <= 6; d++) { if (d == a || d == b || d == c) continue; vi v1, v2, v3; for (int y : permutations) { auto &v = all_per[y]; int ind; for (ind = 0; v[ind] != d; ind++); for (; v[ind] != a && v[ind] != b && v[ind] != c; ind++, ind %= 6); if (v[ind] == a) v1.push_back(y); else if (v[ind] == b) v2.push_back(y); else v3.push_back(y); } if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) { startegy_tree[hash] = {a, b, c, d, 4}; return true; } } } } } for (int a = 1; a <= 6; a++) { for (int b = a + 1; b <= 6; b++) { for (int c = b + 1; c <= 6; c++) { vi v1, v2, v3; for (int y : permutations) { auto &v = all_per[y]; int ind1, ind2, ind3; for (ind1 = 0; v[ind1] != a; ind1++); for (ind2 = 0; v[ind2] != b; ind2++); for (ind3 = 0; v[ind3] != c; ind3++); int i = min({ind1, ind2, ind3}); if (i == ind1) v1.push_back(y); else if (i == ind2) v2.push_back(y); else v3.push_back(y); } if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) { startegy_tree[hash] = {a, b, c, 1}; return true; } } } } for (int a = 1; a <= 6; a++) { for (int b = a + 1; b <= 6; b++) { for (int c = b + 1; c <= 6; c++) { vi v1, v2, v3; for (int y : permutations) { auto &v = all_per[y]; int ind1, ind2, ind3; for (ind1 = 0; v[ind1] != a; ind1++); for (ind2 = 0; v[ind2] != b; ind2++); for (ind3 = 0; v[ind3] != c; ind3++); int i = max({ind1, ind2, ind3}); if (i == ind1) v1.push_back(y); else if (i == ind2) v2.push_back(y); else v3.push_back(y); } if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) { startegy_tree[hash] = {a, b, c, 2}; return true; } } } } return false; } void init(int T) { vi permutations(720); iota(all(permutations), 0); vi v = {1, 2, 3, 4, 5, 6}; do { all_per.push_back(v); } while (next_permutation(all(v))); Solve(permutations, 0); } map<vi, int> asksLight; int queryLight(int a, int b, int c) { vi v = {a, b, c}; sort(all(v)); if (asksLight.count(v)) return asksLight[v]; return asksLight[v] = getLightest(a, b, c); } map<vi, int> asksHeavy; int queryHeavy(int a, int b, int c) { vi v = {a, b, c}; sort(all(v)); if (asksHeavy.count(v)) return asksHeavy[v]; return asksHeavy[v] = getHeaviest(a, b, c); } map<vi, int> asksMed; int queryMed(int a, int b, int c) { vi v = {a, b, c}; sort(all(v)); if (asksMed.count(v)) return asksMed[v]; return asksMed[v] = getMedian(a, b, c); } map<vi, int> asksNext; int queryNext(int a, int b, int c, int d) { vi v = {a, b, c}; sort(all(v)); v.push_back(d); if (asksNext.count(v)) return asksNext[v]; return asksNext[v] = getNextLightest(a, b, c, d); } void orderCoins() { int w[] = {1, 2, 3, 4, 5, 6}; asksLight.clear(); asksHeavy.clear(); asksMed.clear(); asksNext.clear(); vi permutations(720); iota(all(permutations), 0); vi cnt_type(5); while (permutations.size() > 1) { int hash = Hash(permutations); vi v = startegy_tree[hash]; int type = v.back(); cnt_type[type]++; int a = v[0], b = v[1], c = v[2]; vi next; next.reserve(permutations.size() / 3); if (type == 1) { int x = queryLight(a, b, c); for (int y : permutations) { vi &v = all_per[y]; int ind1, ind2, ind3; for (ind1 = 0; v[ind1] != a; ind1++); for (ind2 = 0; v[ind2] != b; ind2++); for (ind3 = 0; v[ind3] != c; ind3++); if (v[min({ind1, ind2, ind3})] == x) next.push_back(y); } } else if (type == 2) { int x = queryHeavy(a, b, c); for (int y : permutations) { vi &v = all_per[y]; int ind1, ind2, ind3; for (ind1 = 0; v[ind1] != a; ind1++); for (ind2 = 0; v[ind2] != b; ind2++); for (ind3 = 0; v[ind3] != c; ind3++); if (v[max({ind1, ind2, ind3})] == x) next.push_back(y); } } else if (type == 3) { int x = queryMed(a, b, c); if (x == b) swap(a, b); if (x == c) swap(a, c); for (int y : permutations) { vi &v = all_per[y]; int ind1, ind2, ind3; for (ind1 = 0; v[ind1] != a; ind1++); for (ind2 = 0; v[ind2] != b; ind2++); for (ind3 = 0; v[ind3] != c; ind3++); if (ind1 != max({ind1, ind2, ind3}) && ind1 != min({ind1, ind2, ind3})) next.push_back(y); } } else { int d = v[3]; int x = queryNext(a, b, c, d); for (int y : permutations) { vi &v = all_per[y]; int ind; for (ind = 0; v[ind] != d; ind++); for (; v[ind] != a && v[ind] != b && v[ind] != c; ind++, ind %= 6); if (v[ind] == x) next.push_back(y); } } swap(permutations, next); } // cout << cnt_type[1] << ' ' << cnt_type[2] << ' ' << cnt_type[3] << ' ' << cnt_type[4] << '\n'; vi v = all_per[permutations[0]]; for (int i = 0; i < 6; i++) w[i] = v[i]; answer(w); }

컴파일 시 표준 에러 (stderr) 메시지

scales.cpp: In function 'int Hash(vi&)':
scales.cpp:23:12: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
   23 |     return ans;
      |            ^~~
scales.cpp: In function 'bool Solve(vi&, int)':
scales.cpp:37:30: warning: conversion from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
   37 |     int n = permutations.size();
      |             ~~~~~~~~~~~~~~~~~^~
scales.cpp: In function 'void init(int)':
scales.cpp:134:15: warning: unused parameter 'T' [-Wunused-parameter]
  134 | void init(int T) {
      |           ~~~~^
scales.cpp: In function 'void orderCoins()':
scales.cpp:197:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  197 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
scales.cpp:207:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  207 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
scales.cpp:219:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  219 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
scales.cpp:230:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  230 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
#Verdict Execution timeMemoryGrader output
Fetching results...