Submission #1273934

#TimeUsernameProblemLanguageResultExecution timeMemory
1273934AvianshScales (IOI15_scales)C++17
100 / 100
323 ms1572 KiB
#include "scales.h" #include <bits/stdc++.h> using namespace std; const int mx = 6; map<vector<vector<int>>,int>mp; map<vector<vector<int>>,pair<int,vector<int>>>mov; vector<int> revers(vector<int>v){ vector<int>ans(mx); for(int i = 0;i<mx;i++){ ans[v[i]]=i; } return ans; } vector<int> cop(vector<int>v){ vector<int>ans; for(int i : v){ ans.push_back(i); } return ans; } int rec(vector<vector<int>>pos, int dep){ if(dep>7){ return 1e9; } if(mp.find(pos)!=mp.end()){ if(mp[pos]==-1){ return 1e9; } return mp[pos]; } if(pos.size()==1){ return 0; } if(pos.size()==0){ mp[pos]=-1e9; return mp[pos]; } int req = 0; for(int i = 0;i<mx;i++){ if(pow(3,i)<pos.size()){ req=i; } } req++; int nx = (int)pow(3,mx-dep); mp[pos]=-1; int ans = 1e9; for(int a = 0;a<mx;a++){ for(int b = a+1;b<mx;b++){ for(int c = b+1;c<mx;c++){ int mov1 = 1e9; int mov2 = 1e9; int mov3 = 1e9; int mov4 = 1e9; int optd=-1; vector<vector<int>>curra,currb,currc; for(vector<int>v:pos){ vector<int>rev = revers(v); if(rev[a]>rev[b]&&rev[a]>rev[c]){ curra.push_back(cop(v)); } else if(rev[b]>rev[a]&&rev[b]>rev[c]){ currb.push_back(cop(v)); } else{ currc.push_back(cop(v)); } } if(max({curra.size(),currb.size(),currc.size()})<=nx){ mov1=max({rec(curra,dep+1),rec(currb,dep+1),rec(currc,dep+1)}); } ans=min({mov1,mov2,mov3,ans,mov4}); if(ans<=req){ if(ans==mov1){ mov[pos]={1,{a,b,c}}; } return (mp[pos]=ans+1); } curra.clear(); currb.clear(); currc.clear(); for(vector<int>v:pos){ vector<int>rev = revers(v); if(rev[a]<rev[b]&&rev[a]<rev[c]){ curra.push_back(cop(v)); } else if(rev[b]<rev[a]&&rev[b]<rev[c]){ currb.push_back(cop(v)); } else{ currc.push_back(cop(v)); } } if(max({curra.size(),currb.size(),currc.size()})<=nx) mov2=max({rec(curra,dep+1),rec(currb,dep+1),rec(currc,dep+1)}); ans=min({mov1,mov2,mov3,ans,mov4}); if(ans<=req){ if(ans==mov2){ mov[pos]={2,{a,b,c}}; } return (mp[pos]=ans+1); } curra.clear(); currb.clear(); currc.clear(); for(vector<int>v:pos){ vector<int>rev = revers(v); int mx = max({rev[a],rev[b],rev[c]}); int mn = min({rev[a],rev[b],rev[c]}); if(mx!=rev[a]&&mn!=rev[a]){ curra.push_back(cop(v)); } else if(mx!=rev[b]&&mn!=rev[b]){ currb.push_back(cop(v)); } else{ currc.push_back(cop(v)); } } if(max({curra.size(),currb.size(),currc.size()})<=nx) mov3=max({rec(curra,dep+1),rec(currb,dep+1),rec(currc,dep+1)}); ans=min({mov1,mov2,mov3,ans,mov4}); if(ans<=req){ if(ans==mov3){ mov[pos]={3,{a,b,c}}; } return (mp[pos]=ans+1); } for(int d = 0;d<mx;d++){ if(a==d||b==d||c==d) continue; curra.clear(); currb.clear(); currc.clear(); for(vector<int>v:pos){ vector<int>rev = revers(v); vector<int>ar = {rev[a],rev[b],rev[c]}; sort(ar.begin(),ar.end()); auto it = lower_bound(ar.begin(),ar.end(),rev[d]); if(it==ar.end()){ it=ar.begin(); } if((*it)==rev[a]){ curra.push_back(cop(v)); } else if((*it)==rev[b]){ currb.push_back(cop(v)); } else{ currc.push_back(cop(v)); } } if(max({curra.size(),currb.size(),currc.size()})<=nx){ mov4=min(mov4,max({rec(curra,dep+1),rec(currb,dep+1),rec(currc,dep+1)})); if(mov4==max({rec(curra,dep+1),rec(currb,dep+1),rec(currc,dep+1)})){ optd=d; } } ans=min({mov1,mov2,mov3,ans,mov4}); if(ans<=req){ if(ans==mov4){ mov[pos]={4,{a,b,c,optd}}; } return (mp[pos]=ans+1); } } } } } if(ans>req){ mp.erase(pos); mov.erase(pos); return 1e9; } return (mp[pos]=ans+1); } int fac(int x){ int ans = 1; for(int i = 1;i<=x;i++){ ans*=i; } return ans; } void init(int T) { vector<vector<int>>pos(fac(mx)); int perm[mx]; iota(perm,perm+mx,0); for(int i = 0;i<fac(mx);i++){ for(int j : perm){ pos[i].push_back(j); } next_permutation(perm,perm+mx); } rec(pos,1); } void orderCoins() { vector<vector<int>>pos(720); int perm[mx]; iota(perm,perm+mx,0); for(int i = 0;i<720;i++){ for(int j : perm){ pos[i].push_back(j); } next_permutation(perm,perm+mx); } int cn = 0; while(pos.size()>1){ assert(mov.find(pos)!=mov.end()); cn++; pair<int,vector<int>>curr = mov[pos]; vector<vector<int>>nx; if(curr.first==1){ int a = curr.second[0]; int b = curr.second[1]; int c = curr.second[2]; int h = getHeaviest(a+1,b+1,c+1)-1; for(vector<int>v:pos){ vector<int>rev = revers(v); if(rev[h]>=rev[a]&&rev[h]>=rev[b]&&rev[h]>=rev[c]){ nx.push_back(cop(v)); } } pos=nx; } else if(curr.first==2){ int a = curr.second[0]; int b = curr.second[1]; int c = curr.second[2]; int h = getLightest(a+1,b+1,c+1)-1; for(vector<int>v:pos){ vector<int>rev = revers(v); if(rev[h]<=rev[a]&&rev[h]<=rev[b]&&rev[h]<=rev[c]){ nx.push_back(cop(v)); } } pos=nx; } else if(curr.first==3){ int a = curr.second[0]; int b = curr.second[1]; int c = curr.second[2]; int h = getMedian(a+1,b+1,c+1)-1; for(vector<int>v:pos){ vector<int>rev = revers(v); int mx = max({rev[a],rev[b],rev[c]}); int mn = min({rev[a],rev[b],rev[c]}); if(mx!=rev[a]&&mn!=rev[a]){ if(a==h) nx.push_back(cop(v)); } else if(mx!=rev[b]&&mn!=rev[b]){ if(b==h) nx.push_back(cop(v)); } else{ if(c==h) nx.push_back(cop(v)); } } pos=nx; } else{ int a = curr.second[0]; int b = curr.second[1]; int c = curr.second[2]; int d = curr.second[3]; int h = getNextLightest(a+1,b+1,c+1,d+1)-1; for(vector<int>v:pos){ vector<int>rev = revers(v); vector<int>ar = {rev[a],rev[b],rev[c]}; sort(ar.begin(),ar.end()); auto it = lower_bound(ar.begin(),ar.end(),rev[d]); if(it==ar.end()){ it=ar.begin(); } if((*it)==rev[a]){ if(a==h) nx.push_back(cop(v)); } else if((*it)==rev[b]){ if(b==h) nx.push_back(cop(v)); } else{ if(c==h) nx.push_back(cop(v)); } } pos=nx; } } int ans[6]; int ind = 0; for(int i : pos[0]){ ans[ind++]=i+1; } answer(ans); }
#Verdict Execution timeMemoryGrader output
Fetching results...