제출 #1165286

#제출 시각아이디문제언어결과실행 시간메모리
1165286SmuggingSpunScales (IOI15_scales)C++17
0 / 100
1083 ms21236 KiB
#include<bits/stdc++.h> #include "scales.h" using namespace std; template<class T>bool minimize(T& a, T b){ if(a > b){ a = b; return true; } return false; } template<class T>void maximize(T& a, T b){ if(a < b){ a = b; } } map<vector<vector<int>>, pair<vector<int>, int>>dp; vector<vector<int>>cd; void get_min_query(vector<vector<int>>& perm, const vector<int>& id, const int r){ cd.clear(); for(vector<int>& p : perm){ bool flag; for(int& x : p){ if(x == id[0] || x == id[1] || x == id[2]){ flag = bool(x == id[r]); break; } } if(flag){ cd.emplace_back(p); } } } void get_max_query(vector<vector<int>>& perm, const vector<int>& id, const int r){ cd.clear(); for(vector<int>& p : perm){ bool flag; for(int i = 5; i > -1; i--){ if(p[i] == id[0] || p[i] == id[1] || p[i] == id[2]){ flag = bool(p[i] == id[r]); break; } } if(flag){ cd.emplace_back(p); } } } void get_median_query(vector<vector<int>>& perm, const vector<int>& id, const int r){ cd.clear(); for(vector<int>& p : perm){ bool flag; for(int& x : p){ if(x == id[0] || x == id[1] || x == id[2]){ flag = bool(x != id[r]); break; } } if(flag){ for(int i = 5; i > -1; i--){ if(p[i] == id[0] || p[i] == id[1] || p[i] == id[2]){ flag = bool(p[i] != id[r]); break; } } if(flag){ cd.emplace_back(p); } } } } void get_next_min_query(vector<vector<int>>& perm, const vector<int>& id, const int r){ cd.clear(); for(vector<int>& p : perm){ vector<int>ord; for(int& x : p){ if(x == id[0] || x == id[1] || x == id[2] || x == id[3]){ ord.emplace_back(x); } } for(int i = 0; i < 4; i++){ if(id[3] == ord[i]){ if((i == 3 && id[r] == ord[0]) || (i < 3 && id[r] == ord[i + 1])){ cd.emplace_back(p); } break; } } } } int dfs(vector<vector<int>>perm){ if(perm.size() == 1){ return 0; } auto it = dp.find(perm); if(it != dp.end()){ return (it->second).second; } int theory_optimal = 0, ans = 8; for(int i = 1; i < perm.size(); i *= 3){ theory_optimal++; } vector<int>query; for(int i = 1; i < 7 && ans > theory_optimal; i++){ for(int j = i + 1; j < 7 && ans > theory_optimal; j++){ for(int k = j + 1; k < 7 && ans > theory_optimal; k++){ vector<int>id = {i, j, k}; vector<vector<int>>_max, _min, _median; int max_min = 0, max_max = 0, max_median = 0; for(int r = 0; r < 3; r++){ if(max_min + 1 < ans){ get_min_query(perm, id, r); maximize(max_min, cd.size() == perm.size() ? 10 : (cd.empty() ? 0 : dfs(cd))); } if(max_max + 1 < ans){ get_max_query(perm, id, r); maximize(max_max, cd.size() == perm.size() ? 10 : (cd.empty() ? 0 : dfs(cd))); } if(max_median + 1 < ans){ get_median_query(perm, id, r); maximize(max_median, cd.size() == perm.size() ? 10 : (cd.empty() ? 0 : dfs(cd))); } } if(minimize(ans, max_min + 1)){ query = id; query.emplace_back(i); } if(minimize(ans, max_max + 1)){ query = id; query.emplace_back(j); } if(minimize(ans, max_median + 1)){ query = id; query.emplace_back(k); } for(int t = k + 1; t < 7; t++){ vector<int>id = {i, j, k, t}; for(int _i = 0; _i < 4 && ans > theory_optimal; _i++){ swap(id[_i], id[3]); int max_next_min = 0; for(int r = 0; r < 3 && max_next_min + 1 < ans; r++){ get_next_min_query(perm, id, r); maximize(max_next_min, cd.size() == perm.size() ? 10 : (cd.empty() ? 0 : dfs(cd))); } if(minimize(ans, max_next_min + 1)){ query = id; } swap(id[_i], id[3]); } } } } } dp[perm] = make_pair(query, ans); return ans; } vector<vector<int>>__perm; void init(int T){ vector<int>_p(6); iota(_p.begin(), _p.end(), 1); do{ __perm.emplace_back(_p); } while(next_permutation(_p.begin(), _p.end())); } int W_ans[6]; void __answer(const vector<int>& ans){ for(int i = 0; i < 6; i++){ W_ans[i] = ans[i]; } answer(W_ans); } bool update_min(vector<vector<int>>& best, vector<vector<int>>cd){ if(best.size() >= cd.size()){ swap(best, cd); return true; } return false; } void update_max(vector<vector<int>>& best, vector<vector<int>>cd){ if(best.size() < cd.size()){ swap(best, cd); } } void orderCoins(){ vector<vector<int>>perm = __perm; while(perm.size() > 100){ vector<vector<int>>best = perm; pair<vector<int>, int>query; for(int i = 1; i < 7; i++){ for(int j = i + 1; j < 7; j++){ for(int k = j + 1; k < 7; k++){ vector<int>id = {i, j, k}; vector<vector<int>>_max, _min, _median; for(int r = 0; r < 3; r++){ get_min_query(perm, id, r); update_max(_min, cd); get_max_query(perm, id, r); update_max(_max, cd); get_median_query(perm, id, r); update_max(_median, cd); } for(int t = k + 1; t < 7; t++){ vector<int>id = {i, j, k, t}; for(int _i = 0; _i < 4; _i++){ swap(id[_i], id[3]); vector<vector<int>>_next_min; for(int r = 0; r < 3; r++){ get_next_min_query(perm, id, r); update_max(_next_min, cd); } if(update_min(best, _next_min)){ query = make_pair(id, 3); } swap(id[_i], id[3]); } } if(update_min(best, _min)){ query = make_pair(id, 0); } if(update_min(best, _max)){ query = make_pair(id, 1); } if(update_min(best, _median)){ query = make_pair(id, 2); } } } } if(query.second == 0){ int x = getLightest(query.first[0], query.first[1], query.first[2]); get_min_query(perm, query.first, x == query.first[0] ? 0 : (x == query.first[1] ? 1 : 2)); perm = cd; } else if(query.second == 1){ int x = getHeaviest(query.first[0], query.first[1], query.first[2]); get_max_query(perm, query.first, x == query.first[0] ? 0 : (x == query.first[1] ? 1 : 2)); perm = cd; } else if(query.second == 2){ int x = getMedian(query.first[0], query.first[1], query.first[2]); get_median_query(perm, query.first, x == query.first[0] ? 0 : (x == query.first[1] ? 1 : 2)); perm = cd; } else{ int x = getNextLightest(query.first[0], query.first[1], query.first[2], query.first[3]); get_next_min_query(perm, query.first, x == query.first[0] ? 0 : (x == query.first[1] ? 1 : 2)); perm = cd; } } while(perm.size() > 1){ dfs(perm); vector<int>& id = dp[perm].first; if(id[0] == id[3]){ int x = getLightest(id[0], id[1], id[2]); get_min_query(perm, id, x == id[0] ? 0 : (x == id[1] ? 1 : 2)); swap(perm, cd); } else if(id[1] == id[3]){ int x = getHeaviest(id[0], id[1], id[2]); get_max_query(perm, id, x == id[0] ? 0 : (x == id[1] ? 1 : 2)); swap(perm, cd); } else if(id[2] == id[3]){ int x = getMedian(id[0], id[1], id[2]); get_median_query(perm, id, x == id[0] ? 0 : (x == id[1] ? 1 : 2)); swap(perm, cd); } else{ int x = getNextLightest(id[0], id[1], id[2], id[3]); get_next_min_query(perm, id, x == id[0] ? 0 : (x == id[1] ? 1 : 2)); swap(perm, cd); } } __answer(perm[0]); }
#Verdict Execution timeMemoryGrader output
Fetching results...