#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 time | Memory | Grader output |
---|
Fetching results... |