c7c7さんの作品(ソースコード)

//------------------------------------------------------------------------------
/// @file
/// @author   ハル研究所プログラミングコンテスト実行委員会
///
/// @copyright  Copyright (c) 2019 HAL Laboratory, Inc.
/// @attention  このファイルの利用は、同梱のREADMEにある
///             利用条件に従ってください。
//------------------------------------------------------------------------------
                      
#include <vector>
#include <unordered_set>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <cassert>
#include <climits>
#include <functional>
#include <iostream>
#include <cstring>
#include <memory>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <set>
        
#include "Answer.hpp"
using namespace std;
                      
unsigned long long xor128() {
    static unsigned long long rx = 1211111831, ry = 4747111469, rz = 5214747629, rw = 84747123;
    unsigned long long rt = (rx ^ (rx << 11));
    rx = ry;
    ry = rz;
    rz = rw;
    return (rw = (rw ^ (rw >> 19)) ^ (rt ^ (rt >> 8)));
}
                      
                      
                      
//------------------------------------------------------------------------------
namespace hpc {
typedef std::pair<int,int>P;
typedef std::pair<int,unordered_set<int> >PS;
#define XX first
#define YY second
int n,m;
std::vector<P> food_A;
std::vector<int> hei;
std::vector<P> turtle;
vector<PS> now;
vector<int>ve[26];
int idx[26]={};
int wait[111][26]={};
int cntttt;
int all_sum;
//------------------------------------------------------------------------------
/// コンストラクタ。
/// @detail 最初のステージ開始前に実行したい処理があればここに書きます。
Answer::Answer()
{
    cntttt=0;
    all_sum=0;
}
                      
//------------------------------------------------------------------------------
/// デストラクタ。
/// @detail 最後のステージ終了後に実行したい処理があればここに書きます。
Answer::~Answer()
{
}
                      
                      
//------------------------------------------------------------------------------
/// 各ステージ開始時に呼び出される処理。
/// @detail 各ステージに対する初期化処理が必要ならここに書きます。
/// @param aStage 現在のステージ。
                      
                      
int A_x[26];
int A_y[26];
int TIME[26];
int pred[111];
int preb[111];
                 
int score1(int ccur=1e9,int MA=1e9){
    for(int i=0;i<m;i++){
        TIME[i]=0;
        A_y[i]=turtle[i].YY;
        A_x[i]=turtle[i].XX;
    }
                      
    int MAX=0;
    P v[26];
                      
    for(int i=0;i<n;i++){
        //if( now[i].second.size()<=n/3 )continue;
        for(int j=0;j<m;j++){
            v[j]=( P( abs(A_x[j]-food_A[now[i].XX].XX) + abs(A_y[j]-food_A[now[i].XX].YY)+TIME[j] , j ) );
        }
        sort(v,v+m);
        int cur = v[(int)now[i].second.size()-1].first;
        for(int j=0;j<(int)now[i].second.size();j++){
            TIME[ v[j].second ] = cur;
            A_x[ v[j].second  ] = food_A[now[i].XX].XX;
            A_y[ v[j].second  ] = food_A[now[i].XX].YY;
        }
        MAX=max(cur,MAX);
    }
    return MAX;
}
             
bool uused[26];
int ABS[60][60];
                 
int score3(int ccur=1e9,int MA=1e9){
    for(int i=0;i<m;i++){
        TIME[i]=0;
        A_y[i]=turtle[i].YY;
        A_x[i]=turtle[i].XX;
    }
                      
    int MAX=0;
    int sum=0;
    P v[26];
                      
    for(int i=0;i<n;i++){
        if( (4<(int)now[i].second.size() && (int)now[i].second.size()<m)){
            for(int j=0;j<m;j++){
                v[j]=( P( (ABS[A_x[j]][food_A[now[i].XX].XX] + ABS[A_y[j]][food_A[now[i].XX].YY]+TIME[j]) , j ) );
            }
            //sort(v,v+m);
            nth_element( v,v+(int)now[i].second.size()-1,v+m );
            int cur = v[(int)now[i].second.size()-1].first;
            for(int j=0;j<(int)now[i].second.size();j++){
               //if(v[j].first>cur)exit(1);
                TIME[ v[j].second ] = cur;
                A_x[ v[j].second  ] = food_A[now[i].XX].XX;
                A_y[ v[j].second  ] = food_A[now[i].XX].YY;
            }
            MAX=max(cur,MAX);
            sum+=cur;
        }
        else if((int)now[i].second.size()==m){
            int TT2=-1;
                for(int j=0;j<m;j++){
                    int dis=ABS[A_x[j]][food_A[now[i].XX].XX] + ABS[A_y[j]][food_A[now[i].XX].YY]+TIME[j];
                    if(TT2<dis){
                        TT2=dis;
                    }
                }
                for(int j=0;j<m;j++){
                    TIME[ j ] = TT2;
                    A_x[ j ] = food_A[now[i].XX].XX;
                    A_y[ j  ] = food_A[now[i].XX].YY;
                }
                MAX=max(TT2,MAX);
                sum+=TT2;
        }
            
        else if((int)now[i].second.size()==1){
                int TT=1e9,id=0;
                for(int j=0;j<m;j++){
                    int dis=ABS[A_x[j]][food_A[now[i].XX].XX] + ABS[A_y[j]][food_A[now[i].XX].YY]+TIME[j];
                    if(TT>dis){
                        TT=dis;
                        id=j;
                    }
                }
                TIME[ id ] = TT;
                A_x[ id ] = food_A[now[i].XX].XX;
                A_y[ id  ] = food_A[now[i].XX].YY;
                MAX=max(TT,MAX);
                sum+=TT;
        }
        else if((int)now[i].second.size()==2){
            int TT=1e9,id=0,TT2=1e9,id2=0;;
                for(int j=0;j<m;j++){
                    int dis=ABS[A_x[j]][food_A[now[i].XX].XX] + ABS[A_y[j]][food_A[now[i].XX].YY]+TIME[j];
                    if(TT2>dis){
                        TT2=dis;
                        id2=j;
                        if(TT>TT2){
                            swap(id2,id);
                            swap(TT,TT2);
                        }
                    }
                }
                TIME[ id ] = TT2;
                A_x[ id ] = food_A[now[i].XX].XX;
                A_y[ id  ] = food_A[now[i].XX].YY;
                TIME[ id2 ] = TT2;
                A_x[ id2 ] = food_A[now[i].XX].XX;
                A_y[ id2  ] = food_A[now[i].XX].YY;
                MAX=max(TT2,MAX);
                sum+=TT2;
        }
                     
        else if((int)now[i].second.size()==3){
            int TT=1e9,id=0,TT2=1e9,id2=0,TT3=1e9,id3=0;;
                for(int j=0;j<m;j++){
                    int dis=ABS[A_x[j]][food_A[now[i].XX].XX] + ABS[A_y[j]][food_A[now[i].XX].YY]+TIME[j];
                    if(TT3>dis){
                        TT3=dis;
                        id3=j;
                        if(TT2>TT3){
                            swap(id2,id3);
                            swap(TT3,TT2);
                            if(TT>TT2){
                                swap(id2,id);
                                swap(TT,TT2);
                            }
                        }
                    }
                }
                TIME[ id ] = TT3;
                A_x[ id ] = food_A[now[i].XX].XX;
                A_y[ id  ] = food_A[now[i].XX].YY;
                TIME[ id2 ] = TT3;
                A_x[ id2 ] = food_A[now[i].XX].XX;
                A_y[ id2  ] = food_A[now[i].XX].YY;
                TIME[ id3 ] = TT3;
                A_x[ id3 ] = food_A[now[i].XX].XX;
                A_y[ id3  ] = food_A[now[i].XX].YY;
                MAX=max(TT3,MAX);
                sum+=TT3;
        }
            
        else if((int)now[i].second.size()==4){
            int TT=1e9,id=0,TT2=1e9,id2=0,TT3=1e9,id3=0,TT4=1e9,id4=0;;
                for(int j=0;j<m;j++){
                    int dis=ABS[A_x[j]][food_A[now[i].XX].XX] + ABS[A_y[j]][food_A[now[i].XX].YY]+TIME[j];
                    if(TT4>dis){
                        TT4=dis;
                        id4=j;
                        if(TT3>TT4){
                            swap(id4,id3);
                            swap(TT3,TT4);
                            if(TT2>TT3){
                                swap(id2,id3);
                                swap(TT3,TT2);
                                if(TT>TT2){
                                    swap(id2,id);
                                    swap(TT,TT2);
                                }
                            }
                        }
                    }
                }
                TIME[ id ] = TT4;
                A_x[ id ] = food_A[now[i].XX].XX;
                A_y[ id  ] = food_A[now[i].XX].YY;
                TIME[ id2 ] = TT4;
                A_x[ id2 ] = food_A[now[i].XX].XX;
                A_y[ id2  ] = food_A[now[i].XX].YY;
                TIME[ id3 ] = TT4;
                A_x[ id3 ] = food_A[now[i].XX].XX;
                A_y[ id3  ] = food_A[now[i].XX].YY;
                TIME[ id4 ] = TT4;
                A_x[ id4 ] = food_A[now[i].XX].XX;
                A_y[ id4  ] = food_A[now[i].XX].YY;
                MAX=max(TT4,MAX);
                sum+=TT4;
        }
           
        if(preb[i]+20 <= MAX )return 1e9;
        pred[i] = MAX;
        if(MAX>ccur)return 1e9;
    }
    for(int i=0;i<n;i++){
        preb[i]=pred[i];
    }
    return MAX;
}
        
int score4(){
    for(int i=0;i<26;i++)ve[i].clear();
                    
    for(int i=0;i<m;i++){
        TIME[i]=0;
        A_y[i]=turtle[i].YY;
        A_x[i]=turtle[i].XX;
    }
                      
    int MAX=0;
                      
    for(int i=0;i<n;i++){
        vector<P>v;
        for(int j=0;j<m;j++){
            v.push_back( P( abs(A_x[j]-food_A[now[i].XX].XX) + abs(A_y[j]-food_A[now[i].XX].YY) + TIME[j] , j ) );
        }
        sort(v.begin(),v.end());
        int cur = v[(int)now[i].second.size()-1].first;
        for(int j=0;j<(int)now[i].second.size();j++){
            TIME[ v[j].second ] = cur;
            A_x[ v[j].second  ] = food_A[now[i].XX].XX;
            A_y[ v[j].second  ] = food_A[now[i].XX].YY;
            ve[ v[j].second ].push_back( now[i].first );
        }
        MAX=max(cur,MAX);
    }
    return MAX;
}
        
int score_perm(int TTT){
  for(int i=0;i<m;i++){
        TIME[i]=0;
        A_y[i]=turtle[i].YY;
        A_x[i]=turtle[i].XX;
    }
                      
    int MAX=0;
        
    vector<int>per;
    int XXX=0;
                      
    for(int i=0;i<n;i+=5){
        if(i+5==n)XXX=5;
        vector<int>num;
        for(int j=i;j<i+10;j++)num.push_back(j);
        
        vector<int> time(26),a_y(26),a_x(26);
        vector<int> atime(26),aa_y(26),aa_x(26);
        vector<int> btime(26),b_y(26),b_x(26);
        vector<int>GG;
        for(int j=0;j<m;j++){
            time[j]=TIME[j];
            a_y[j]=A_y[j];
            a_x[j]=A_x[j];
        }
        
        int MAS=1e9;
        do{
            for(int j=0;j<m;j++){
                time[j]=TIME[j];
                a_y[j]=A_y[j];
                a_x[j]=A_x[j];
                btime[j]=TIME[j];
                b_y[j]=A_y[j];
                b_x[j]=A_x[j];
            }
        
            int MAX2=0;
//            int TA,TB,TC;
        
            for(int k=0;k<10-XXX;k++){
        
                vector<P>v;
        
                for(int j=0;j<m;j++){
                    v.push_back( P( abs(a_x[j]-food_A[now[num[k]].XX].XX) + abs(a_y[j]-food_A[now[num[k]].XX].YY) + time[j] , j ) );
                }
                sort(v.begin(),v.end());
                int cur = v[(int)now[num[k]].second.size()-1].first;
                for(int j=0;j<(int)now[num[k]].second.size();j++){
                    if(k<5){
                        btime[ v[j].second ] = cur;
                        b_x[ v[j].second  ] = food_A[now[num[k]].XX].XX;
                        b_y[ v[j].second  ] = food_A[now[num[k]].XX].YY;
                    }
                    time[ v[j].second ] = cur;
                    a_x[ v[j].second  ] = food_A[now[num[k]].XX].XX;
                    a_y[ v[j].second  ] = food_A[now[num[k]].XX].YY;
        
                    //ve[ v[j].second ].push_back( now[i].first );
                }
                MAX2=max(cur,MAX2);
            }
            if(MAX2<MAS){
                atime=btime;
                aa_y=b_y;
                aa_x=b_x;
                MAS=MAX2;
                GG=num;
                //cout<<MAS<<endl;
            }
           // for(int j=0;j<5;j++)cout<<num[j]<<' ';
             //   cout<<endl;
        
        }while(next_permutation(num.begin(),num.begin()+5));
    //exit(0);
        
        MAX = MAS;
        
        for(int j=0;j<m;j++){
            //cout<<atime[j]<<' ';
            TIME[j]=atime[j];
            A_y[j]=aa_y[j];
            A_x[j]=aa_x[j];
        }
        for(int j=0;j<5;j++){
            per.push_back(GG[j]);
        }
       // for(int j=0;j<5;j++)cerr<<num[j]<<' ';
        //    cerr<<endl;
        //cout<<endl;
        //cout<<MAS<<endl;
    }
    //return TTT>MAX?TTT-MAX:0;
if(TTT > MAX){
    vector<PS>nex;
    for(int i=0;i<n;i++){
        nex.push_back(now[per[i]]);
    }
        
    now=nex;
}
    return TTT>MAX?TTT-MAX:0;
}
                 
int init1(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY<15 && food_A[i].XX>=20){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY>=15 && food_A[i].XX>=20){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY>=15 && food_A[i].XX<20){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY<15 && food_A[i].XX<20){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==0)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    //cerr<<score1()<<' '<<score_perm()<<endl;
    return score1();
}
                 
int init2(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY<15 && food_A[i].XX<=40){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY>=15 && food_A[i].XX<=40){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY>=15 && food_A[i].XX>40){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY<15 && food_A[i].XX>40){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==1||k==2)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    //cerr<<now.size()<<endl;
    return score1();
}
                 
int init3(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY>=15 && food_A[i].XX>=20){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY<15 && food_A[i].XX>=20){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY<15 && food_A[i].XX<20){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY>=15 && food_A[i].XX<20){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==0||k==3)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    return score1();
}
                 
int init4(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY>=15 && food_A[i].XX<=40){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY<15 && food_A[i].XX<=40){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY<15 && food_A[i].XX>40){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY>=15 && food_A[i].XX>40){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==1||k==2||k==3)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    //cerr<<now.size()<<endl;
    return score1();
}
int init5(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY<15 && food_A[i].XX>=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY>=15 && food_A[i].XX>=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY>=15 && food_A[i].XX<30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY<15 && food_A[i].XX<30){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==0)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    return score1();
}
                 
int init6(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY<15 && food_A[i].XX<=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY>=15 && food_A[i].XX<=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY>=15 && food_A[i].XX>30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY<15 && food_A[i].XX>30){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==1||k==2)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    //cerr<<now.size()<<endl;
    return score1();
}
                 
int init7(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY>=15 && food_A[i].XX>=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY<15 && food_A[i].XX>=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY<15 && food_A[i].XX<30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY>=15 && food_A[i].XX<30){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==0||k==3)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    return score1();
}
                 
int init8(){
    now.clear();
    for(int k=0;k<4;k++){
        vector<P>ok;
        for(int i=0;i<n;i++){
            if(k==0 && food_A[i].YY>=15 && food_A[i].XX<=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==1 && food_A[i].YY<15 && food_A[i].XX<=30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==2 && food_A[i].YY<15 && food_A[i].XX>30){
                ok.push_back( P(food_A[i].XX,i) );
            }
            if(k==3 && food_A[i].YY>=15 && food_A[i].XX>30){
                ok.push_back( P(food_A[i].YY,i) );
            }
        }
        if(k==1||k==2||k==3)sort(ok.begin(),ok.end());
        else sort(ok.begin(),ok.end(),greater<P>());
                   
        for(int i=0;i<(int)ok.size();i++){
            unordered_set<int>st;
            for(int j=0;j<hei[ok[i].YY];j++)st.insert(j);
            now.push_back(PS(ok[i].YY,st));
        }
    }
    //cerr<<now.size()<<endl;
    return score1();
}
                
void Answer::initialize(const Stage& aStage)
{
    cntttt++;
    for(int i=0;i<60;i++){
        for(int j=0;j<60;j++){
            ABS[i][j]=abs(i-j);
        }
    }
    memset(idx,0,sizeof(idx));
                      
    n = 0 , m = 0;
    food_A.clear();
    turtle.clear();
    hei.clear();
    now.clear();
                      
                      
    for (Food food : aStage.foods()){
        Point A=food.pos();
        food_A.push_back(P(A.x,A.y));
        hei.push_back(food.height());
        n++;
    }
    for (Point turtlePosition : aStage.turtlePositions()){
        turtle.push_back(P(turtlePosition.x,turtlePosition.y));
        m++;
    }
                 
    vector<P>vec;
    vec.push_back(P(init1(),1));
    vec.push_back(P(init2(),2));
    vec.push_back(P(init3(),3));
    vec.push_back(P(init4(),4));
    vec.push_back(P(init5(),5));
    vec.push_back(P(init6(),6));
    vec.push_back(P(init7(),7));
    vec.push_back(P(init8(),8));
                 
    sort(vec.begin(),vec.end());
vector<PS>TTX;
int zer=0;
int MMM=58500;
int XX=2;
if( n==40 )XX=3 , MMM=39500;
//if( n==60 )XX=3 , MMM=40000;
    
for(int o=0;o<XX;o++){
    //if(cntttt<=1)break;
    for(int i=0;i<111;i++)preb[i]=1e9;
    int cur;
    if(vec[o].YY==1)cur=init1();
    if(vec[o].YY==2)cur=init2();
    if(vec[o].YY==3)cur=init3();
    if(vec[o].YY==4)cur=init4();
    if(vec[o].YY==5)cur=init5();
    if(vec[o].YY==6)cur=init6();
    if(vec[o].YY==7)cur=init7();
    if(vec[o].YY==8)cur=init8();
                 
    cur = score3();
                   
    //if(m<10)MMM*=2;
        
    int YY=20;
    if(n==40)YY=20;
    if(n==60)YY=15;
    if(n==80)YY=12;
    if(n==100)YY=10;
    for(int aaa=0;aaa<MMM;aaa++){
                   
        int w=xor128()%2;
        
        int l=xor128()%n;
        int r=xor128()%n;
                   
        if(l>r)swap(l,r);
        if(l==r)continue;
    
        if( w && hei[now[r].XX]>n/2 )continue;
        if( !w && hei[now[l].XX]>n/2 )continue;
        
        
        if(w)for(int i=r;i>l;i--)swap(now[i-1],now[i]);
        else for(int i=l;i<r;i++)swap(now[i+1],now[i]);
        int NG=0;
        if(w&&1<l&&l<n-1){
            int A1=abs(food_A[now[l-2].first].XX-food_A[now[l].first].XX);
            int B1=abs(food_A[now[l-2].first].YY-food_A[now[l].first].YY);
            int A=abs(food_A[now[l-1].first].XX-food_A[now[l].first].XX);
            int B=abs(food_A[now[l-1].first].YY-food_A[now[l].first].YY);
            int C=abs(food_A[now[l+1].first].XX-food_A[now[l].first].XX);
            int D=abs(food_A[now[l+1].first].YY-food_A[now[l].first].YY);
            int C1=abs(food_A[now[l+2].first].XX-food_A[now[l].first].XX);
            int D1=abs(food_A[now[l+2].first].YY-food_A[now[l].first].YY);
            //cerr<<A+B+C+D<<endl;
            if(min((A+B+A1+B1)/2,(C+D+C1+D1)/2)>YY)NG=1;
                    
        }
        if(!w&&1<r&&r<n-1){
            int A1=abs(food_A[now[r-2].first].XX-food_A[now[r].first].XX);
            int B1=abs(food_A[now[r-2].first].YY-food_A[now[r].first].YY);
            int A=abs(food_A[now[r-1].first].XX-food_A[now[r].first].XX);
            int B=abs(food_A[now[r-1].first].YY-food_A[now[r].first].YY);
            int C=abs(food_A[now[r+1].first].XX-food_A[now[r].first].XX);
            int D=abs(food_A[now[r+1].first].YY-food_A[now[r].first].YY);
            int C1=abs(food_A[now[r+2].first].XX-food_A[now[r].first].XX);
            int D1=abs(food_A[now[r+2].first].YY-food_A[now[r].first].YY);
            //cerr<<A+B+C+D<<endl;
            if(min((A+B+A1+B1)/2,(C+D+C1+D1)/2)>YY)NG=1;
        }
                
        int nex;
        if(!NG)nex=score3(cur,cur/20);
                   
        if(!NG && nex<=cur){
            cur=nex;
        
        }
        else{
           // L:;
            if(w)for(int i=l;i<r;i++)swap(now[i],now[i+1]);
            else for(int i=r;i>l;i--)swap(now[i],now[i-1]);
        }
        
                           
                   
    }
    if(!o){
        zer=cur;
        TTX=now;
    }
    else{
        if(cur<zer){
            zer=cur;
            TTX=now;
        }
    }
                   
}
    now=TTX;
    int AA=score4();
   // all_sum += score_perm(AA);
    //AA=score4();
    cerr<<cntttt<<' '<<AA<<' '<<endl;
    //cerr<<all_sum<<endl;
   // cerr << LLL<<' '<<RRR<<endl;
    //all_sum += score_perm(AA);
    //cerr<<all_sum<<endl;
    //if(cntttt==240)cerr<<all_sum<<endl;
    //exit(0);
                          
}
                      
//------------------------------------------------------------------------------
/// 各ターンのカメの行動を指定する。
/// @detail 各カメの行動を指定し、aActionsの要素に追加してください。
///         aActions[i]がi番目のカメの行動になります。
///         aActionsの要素数がaStage.turtlePositions()の要素数と異なる場合、アサートに失敗します。
/// @param[in] aStage 現在のステージ。
/// @param[out] aActions 各カメの行動を指定する配列。
void Answer::setActions(const Stage& aStage, Actions& aActions)
{
    Point targetFoodPosition;
    int cnt2=0;
    for (Point turtlePosition : aStage.turtlePositions()) {
        L:;
        int cnt=0;
                      
        for (Food food : aStage.foods()){
                      
            if (idx[cnt2]<(int)ve[cnt2].size() && cnt==ve[cnt2][idx[cnt2]] && food.isEaten()){
                idx[cnt2]++;
                goto L;
            }
                   
            targetFoodPosition = food.pos();
                   
            if (idx[cnt2]<(int)ve[cnt2].size() && cnt==ve[cnt2][idx[cnt2]] && !food.isEaten())
            {
                if (turtlePosition.x < targetFoodPosition.x) {
                    aActions.add(Action_MoveRight);
                } else if (turtlePosition.x > targetFoodPosition.x) {
                    aActions.add(Action_MoveLeft);
                } else if (turtlePosition.y < targetFoodPosition.y) {
                    aActions.add(Action_MoveDown);
                } else if (turtlePosition.y > targetFoodPosition.y) {
                    aActions.add(Action_MoveUp);
                } else{
                    aActions.add(Action_Wait);
                }
                break;
            }
            if(cnt==n-1){
                aActions.add(Action_Wait);
            }
            cnt++;
        }
        cnt2++;
    }
                      
                      
}
                      
//------------------------------------------------------------------------------
/// 各ステージ終了時に呼び出される処理。
/// @detail 各ステージに対する終了処理が必要ならここに書きます。
/// @param aStage 現在のステージ。
void Answer::finalize(const Stage& aStage)
{
}
}