Language: C

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <limits>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <tuple>
#include <iomanip>
#include <functional>
#include <complex>
#include <array>

using namespace std;
template<class T,class U>inline constexpr bool chmin(T&a,const U b){if(a<=b)return false;a=b;return true;}
template<class T,class U>inline constexpr bool chmax(T&a,const U b){if(a>=b)return false;a=b;return true;}
using pii=pair<int,int>;

//要素数n 初期値x
template<typename T>
inline vector<T> vmake(size_t n,T x){
  return vector<T>(n,x);
}

//a,b,c,x data[a][b][c] 初期値x
template<typename... Args>
auto vmake(size_t n,Args... args){
    auto v=vmake(args...);
    return vector<decltype(v)>(n,move(v));
}

constexpr int MAX=(1<<30)-1;
int dx[]={0,1,-1,0},dy[]={1,0,0,-1};

vector<string> C;
int height,width;
map<string,int> to_number;
map<int,string> to_mozi;
vector<vector<bool>> C_used;

int alive_mine;


//pacID,typeID,hight,width,speedleft,cooldown
vector<array<int,6>> MINE,ENEMY;
vector<pii> SuperPellet,Pellet;
set<pii> set_Pellet;

vector<vector<vector<vector<int>>>> Distance;
vector<vector<vector<vector<pii>>>> connect_Distance;


vector<vector<int>> make_distance(int sh,int sw){
    auto dist=vmake(height,width,MAX);
    queue<pii> que;
    que.emplace(sh,sw);
    dist[sh][sw]=0;
    while(!que.empty()){
        int h,w;
        tie(h,w)=que.front(); que.pop();
        for(int i=0;i<4;i++){
            int nh=h+dx[i],nw=w+dy[i];
            nh=(nh+height)%height;nw=(nw+width)%width;
            if(C[nh][nw]=='#') continue;
            if(dist[nh][nw]>dist[h][w]+1){
                dist[nh][nw]=dist[h][w]+1;
                que.emplace(nh,nw);
            }
        }
    }
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            if(dist[i][j]==MAX) continue;
            connect_Distance[sh][sw][dist[i][j]].push_back(pii(i,j));
        }
    }
    return dist;
}

int find_distance(array<int,6> &x,pii y){
    return Distance[x[2]][x[3]][y.first][y.second];
}
int find_distance(array<int,6> &x,array<int,6> &y){
    return Distance[x[2]][x[3]][y[2]][y[3]];
}

int find_distance(pii x,pii y){
    return Distance[x.first][x.second][y.first][y.second];
}


//sh,swの位置からx距離のところでth,twとの最も遠い位置を求める
pii social_distance(int sh,int sw,int th,int tw,int x){
    int max_dist=-1;
    pii ret;
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            if(Distance[sh][sw][i][j]>x) continue;
            if(chmax(max_dist,Distance[th][tw][i][j])){
                ret=pii(i,j);
            }
        }
    }
    return ret;
}

//距離が2以下のところに敵がいたらそれに勝つように変化させる
//cooldownが終わってなかったら無視
//距離が近い方を優先
void type_switch(){
    for(auto v=MINE.begin();v!=MINE.end();){
        int dist=1000;
        auto mine=*v;
        int cnt=0;
        int number;
        if(mine[5]){
            v++;continue;
        }
        for(auto enemy:ENEMY){
            int tmp=find_distance(mine,enemy);
            if(chmin(dist,tmp)){
                number=cnt;
            }
            cnt++;
        }
        if(dist>4){
            v++; continue;
        }else{
            int next_hand=(ENEMY[number][1]+1)%3;
            if(mine[5]!=0 and ((mine[1]+1)%3==ENEMY[number][1] or ENEMY[number][5]<=1)){ //switchできない かつ　相手は変えれるかそのまま勝てるか
                pii to;
                if(mine[4]>0) to=social_distance(mine[2],mine[3],ENEMY[number][2],ENEMY[number][3],2);
                else to=social_distance(mine[2],mine[3],ENEMY[number][2],ENEMY[number][3],1);
                cout<<"MOVE "<<mine[0]<<" "<<to.second<<" "<<to.first<<"|";
                v=MINE.erase(v);
            }else if(dist==1 or(dist==2 and ENEMY[number][4])){
                cout<<"SWITCH "<<mine[0]<<" "<<to_mozi[next_hand]<<"|";
                v=MINE.erase(v);
            }else if(dist==2 or (dist==3 or (ENEMY[number][4] or mine[4] ) ) or (dist==4 and mine[4] and ENEMY[number][4])){
                v=MINE.erase(v);
            }else v++;
        }
    }
}

void use_Super_dfs(int idx,int value_max,int number,vector<int> &koho,vector<int> &ans,int &min_sum){
    if(idx==number){
        //同じのがあったら弾く
        for(int i=0;i<number;i++){
            for(int j=i+1;j<number;j++){
                if(koho[i]==koho[j]) return;
            }
        }
        //総和を出す
        int tmp_sum=0;
        for(int i=0;i<number;i++){
            if((int)MINE.size()<=koho[i]) continue;
            tmp_sum+=find_distance(MINE[koho[i]],SuperPellet[i]);
        }
        if(chmin(min_sum,tmp_sum)){
            ans=koho;
        }
        return;
    }
    for(int i=0;i<value_max;i++){
        koho[idx]=i;
        use_Super_dfs(idx+1,value_max,number,koho,ans,min_sum);
    }
}

void use_Super(){
    int Super_num=(int)SuperPellet.size();
    vector<int> koho(Super_num);
    vector<int> ans;
    int min_sum=1000000;
    int value_max=max(Super_num,(int)MINE.size());
    use_Super_dfs(0,value_max,Super_num,koho,ans,min_sum);
    int cnt=0;
    for(auto m=MINE.begin();m!=MINE.end();cnt++){
        auto x=*m;
        int num=-1;
        for(int i=0;i<(int)ans.size();i++){
            if(cnt==ans[i]) num=i;
        }
        if(num!=-1){
            cout<<"MOVE "<<x[0]<<" "<<SuperPellet[num].second<<" "<<SuperPellet[num].first<<"|";
            m=MINE.erase(m);
        }else{
            m++;
        }
    }
}

vector<vector<int>> Point;

vector<pii> king_Point;

void set_Point(){
    Pellet.clear();
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            if(C_used[i][j]==false) Pellet.emplace_back(i,j);
        }
    }
    Point=vmake(height,width,0);
    for(int i=0;i<Pellet.size();i++){
        for(int d=0;d<=2;d++){
            for(auto p:connect_Distance[Pellet[i].first][Pellet[i].second][d]){
                Point[p.first][p.second]+=(5-d);
            }
        }
    }
    using T=tuple<int,int,int>;
    priority_queue<T> que;
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            que.emplace(Point[i][j],i,j);
        }
    }
    king_Point.clear();
    while(king_Point.size()<MINE.size() and que.size()){
        int p,h,w;
        tie(p,h,w)=que.top(); que.pop();
        bool flag=true;
        for(auto kp:king_Point){
            if(find_distance(pii(h,w),kp)<=5) flag=false;
        }
        king_Point.emplace_back(h,w);
    }
}

void use_Normal(){
    sort(MINE.begin(),MINE.end());
    cerr<<Pellet.size()<<endl;
    if(Pellet.size()){
        for(auto m:MINE){
            int min_dist=2000;
            int number=-1;
            for(int i=0;i<Pellet.size();i++){
                if(chmin(min_dist,find_distance(m,Pellet[i]))){
                    number=i;
                }
            }
            pii to=Pellet[number];
            cerr<<m[0]<<" "<<find_distance(m,to)<<endl;
            if(m[4] and find_distance(m,to)==1){
                bool flag=false;
                //Palletがあるか
                for(int i=0;i<4;i++){
                    int nh=m[2]+dx[i],nw=m[3]+dy[i];
                    nh=(nh+height)%height;
                    nw=(nw+width)%width;
                    if(set_Pellet.find(pii(nh,nw))!=set_Pellet.end()){
                        to=pii(nh,nw);
                        flag=true;
                    }
                }
                if(!flag){
                    for(int i=0;i<4;i++){
                        int nh=m[2]+dx[i],nw=m[3]+dy[i];
                        nh=(nh+height)%height;
                        nw=(nw+width)%width;
                        if(C_used[nh][nw]==false){
                            to=pii(nh,nw);
                        }
                    }
                }
            }
            cout<<"MOVE "<<m[0]<<" "<<to.second<<" "<<to.first<<"|";
        }
        return;
    }
    set_Point();
    for(auto kp:king_Point){
        int min_dist=2000;
        int number=-1;
        for(int i=0;i<MINE.size();i++){
            if(chmin(min_dist,find_distance(MINE[i],kp))){
                number=i;
            }
        }
        if(number==-1) return;
        cout<<"MOVE "<<MINE[number][0]<<" "<<kp.second<<" "<<kp.first<<"|";
        MINE.erase(MINE.begin()+number);
    }
    



    /*for(auto m:MINE){
        int min_dist=2000;
        pii to={-1,-1};
        int cnt=0;
        for(auto p:Pellet){
            if(chmin(min_dist,find_distance(m,p)+((cnt<cnt_Pellet)?0:4))){
                to=p;
            }
            cnt++;
        }
        if(m[4] and find_distance(m,to)==1){
            bool flag=false;
            //Palletがあるか
            for(int i=0;i<4;i++){
                int nh=m[2]+dx[i],nw=m[3]+dy[i];
                nh=(nh+height)%height;
                nw=(nw+width)%width;
                if(set_Pellet.find(pii(nh,nw))!=set_Pellet.end()){
                    to=pii(nh,nw);
                    flag=true;
                }
            }
            if(!flag){
            for(int i=0;i<4;i++){
                int nh=m[2]+dx[i],nw=m[3]+dy[i];
                nh=(nh+height)%height;
                nw=(nw+width)%width;
                if(C_used[nh][nw]==false){
                    to=pii(nh,nw);
                }
            }
            }
        }
        cout<<"MOVE "<<m[0]<<" "<<to.second<<" "<<to.first<<"|";
    }*/
}


void Game_init(){
    to_mozi[0]="ROCK";
    to_mozi[1]="PAPER";
    to_mozi[2]="SCISSORS";
    to_mozi[3]="ROCK";
    to_number["ROCK"]=0;
    to_number["PAPER"]=1;
    to_number["SCISSORS"]=2;

    cin >> width >> height; cin.ignore();
    C.resize(height);
    C_used=vmake(height,width,false);
    connect_Distance=vmake(height,width,500,vector<pii>());
    for (int i = 0; i < height; i++) {
        string row;
        getline(cin,row);
        C[i]=row;
    }
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            if(C[i][j]=='#') C_used[i][j]=true;
        }
    }

}

//ID,離れたいid,turn
vector<array<int,3>> skip;
vector<pii> PLACE(5);

void do_collision(){
    for(int i=0;i<MINE.size();i++){
        for(int j=i+1;j<MINE.size();j++){
            if(find_distance(MINE[i],MINE[j])<=2){
                cerr<<MINE[i][0]<<" "<<MINE[j][0]<<endl;
                skip.push_back({MINE[i][0],MINE[j][0],2});
                skip.push_back({MINE[j][0],MINE[i][0],2});
            }
        }
    }
}

void do_skip(){
    for(auto m=MINE.begin();m!=MINE.end();){
        auto x=*m;
        bool flag=false;
        for(int i=0;i<skip.size();i++){
            if(x[0]==skip[i][0]){
                pii to;
                if(x[4]>0) to=social_distance(PLACE[x[0]].first,PLACE[x[0]].second,PLACE[skip[i][1]].first,PLACE[skip[i][1]].second,2);
                else to=social_distance(PLACE[x[0]].first,PLACE[x[0]].second,PLACE[skip[i][1]].first,PLACE[skip[i][1]].second,1);

                cout<<"MOVE "<<x[0]<<" "<<to.second<<" "<<to.first<<"|";
                PLACE[x[0]]=to;
                m=MINE.erase(m);
                flag=true;
                break;
            }
            if(flag) break;
        }
        if(flag) continue;
        m++;
    }
}

void do_speed(){
    for(auto m=MINE.begin();m!=MINE.end();){
        auto x=*m;
        if(x[4]==0 and x[5]==0){
            cout<<"SPEED "<<x[0]<<"|";
            m=MINE.erase(m);
        }else{
            m++;
        }
    }
}

void Turn_init(){
    MINE.clear();
    ENEMY.clear();
    SuperPellet.clear();
    Pellet.clear();
    set_Pellet.clear();
    for(auto s=skip.begin();s!=skip.end();){
        (*s)[2]--;;
        if((*s)[2]<0){
            s=skip.erase(s);
        }else s++;
    }
}

void kakutei_Beam(){
    for(int i=0;i<MINE.size();i++){
        int h,w;
        h=MINE[i][2];
        w=MINE[i][3];
        for(int th=0;th<height;th++){
            if(find_distance(pii(h,w),pii(th,w))==abs(th-h) and set_Pellet.find(pii(th,w))==set_Pellet.end()){
                C[th][w]=true;
            }
        }
        for(int tw=0;tw<width;tw++){
            if(find_distance(pii(h,w),pii(h,tw))==abs(tw-w) and set_Pellet.find(pii(h,tw))==set_Pellet.end()){
                C[h][tw]=true;
            }
        }
    }
}


int main()
{
    Game_init();
    Distance=vmake(height,width,height,width,0); 
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            if(C[i][j]=='#') continue;
            Distance[i][j]=make_distance(i,j);
        }
    }
    // game loop
    while (1) {
        Turn_init();
        int myScore;
        int opponentScore;
        cin >> myScore >> opponentScore; cin.ignore();
        int visiblePacCount; // all your pacs and enemy pacs in sight
        cin >> visiblePacCount; cin.ignore();
        for (int i = 0; i < visiblePacCount; i++) {
            int pacId; // pac number (unique within a team)
            bool mine; // true if this pac is yours
            int x; // position in the grid
            int y; // position in the grid
            string typeId; // unused in wood leagues
            int speedTurnsLeft; // unused in wood leagues
            int abilityCooldown; // unused in wood leagues
            cin >> pacId >> mine >> x >> y >> typeId >> speedTurnsLeft >> abilityCooldown; cin.ignore();
            if(mine){
                PLACE[pacId]=pii(y,x);
                C_used[y][x]=true;
                MINE.push_back({pacId,to_number[typeId],y,x,speedTurnsLeft,abilityCooldown});
            }else{
                ENEMY.push_back({pacId,to_number[typeId],y,x,speedTurnsLeft,abilityCooldown});
            }
        }
        alive_mine=MINE.size();

        int visiblePelletCount; // all pellets in sight
        cin >> visiblePelletCount; cin.ignore();
        for (int i = 0; i < visiblePelletCount; i++) {
            // amount of points this pellet is worth
            int h,w,v;
            cin >> w >> h >> v; cin.ignore();
            if(v==10){
                set_Pellet.insert(pii(h,w));
                SuperPellet.emplace_back(h,w);
            }else{
                set_Pellet.insert(pii(h,w));
                Pellet.emplace_back(h,w);
            }
        }
        kakutei_Beam();

        type_switch();
        do_speed();
        do_collision();
        do_skip();
        use_Super();
        use_Normal();
        cout<<endl;
        // Write an action using cout. DON'T FORGET THE "<< endl"
        // To debug: cerr << "Debug messages..." << endl;
    }
}


Compiler output:
main.c:1:10: fatal error: cassert: No such file or directory
    1 | #include <cassert>
      |          ^~~~~~~~~
compilation terminated.