結果

問題 No.5015 Escape from Labyrinth
コンテスト
ユーザー FplusFplusF
提出日時 2026-05-10 14:42:31
言語 C++23
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 174 ms / 3,000 ms
コード長 7,126 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,757 ms
コンパイル使用メモリ 350,588 KB
実行使用メモリ 6,400 KB
スコア 157,010
最終ジャッジ日時 2026-05-10 14:42:58
合計ジャッジ時間 20,185 ms
ジャッジサーバーID
(参考情報)
judge3_0 / judge1_1
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 100
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
using namespace std;
using pii=pair<int,int>;
using tii=tuple<int,int,int>;
using qii=tuple<int,int,int,int>;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
constexpr int INF=1e9;
constexpr ll INF_ll=1e18;
#define rep(i,n) for (int i=0;i<(int)(n);i++)
#define replr(i,l,r) for (int i=(int)(l);i<(int)(r);i++)
#define all(v) v.begin(),v.end()
#define len(v) ((int)v.size())
template<class T> inline bool chmin(T &a,T b){
    if(a>b){
        a=b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T &a,T b){
    if(a<b){
        a=b;
        return true;
    }
    return false;
}

template<class T> inline bool chmin_ref(T &a,const T &b){
    if(a>b){
        a=b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax_ref(T &a,const T &b){
    if(a<b){
        a=b;
        return true;
    }
    return false;
}

namespace Timer{
    chrono::steady_clock::time_point program_start,start;
    void program_start_snap(){
        program_start=start=chrono::steady_clock::now();
    }
    void snap(){
        start=chrono::steady_clock::now();
    }
    int get_ms(){
        auto now=chrono::steady_clock::now();
        int ms=chrono::duration_cast<chrono::milliseconds>(now-start).count();
        return ms;
    }
    int get_ms_all_program(){
        auto now=chrono::steady_clock::now();
        int ms=chrono::duration_cast<chrono::milliseconds>(now-program_start).count();
        return ms;
    }
}

mt19937 mt;
uint32_t rand_int(uint32_t r){  //[0,r)
    assert(r!=0);
    return ((uint64_t)mt()*r)>>32;
}
int rand_int(int l,int r){  //[l,r)
    assert(l<r);
    return l+rand_int(r-l);
}
constexpr double one_div_mt_max=1.0/(double)mt19937::max();
double rand_double(){  //[0.0,1.0]
    return mt()*one_div_mt_max;
}
double rand_double(double l,double r){  //[l,r]
    return l+rand_double()*(r-l);
}
template<class T> T get_random_element(const vector<T> &v){
    assert(!v.empty());
    return v[rand_int(len(v))];
}

template<class T> void add(vector<T> &a,vector<T> b){
    for(auto i:b) a.push_back(i);
}

constexpr int N=60,H=1500,L=60;

int D,M;

string S;

constexpr string UDLR="UDLR";

vector<int> P,K;

array<array<int,5>,N*N> G;

int Start,Key,Goal;

int one(int i,int j){
    return i*N+j;
}
pii two(int x){
    return {x/N,x%N};
}

namespace Solver{
    array<array<int,L>,N*N> grid_damage;
    
    pair<array<int,N*N>,array<int,N*N>> dijkstra(int s,int start_turn,bool goal_ng){
        array<int,N*N> cost,turn;
        array<int,N*N> pre;
        cost.fill(INF);
        turn.fill(-1);
        pre.fill(-1);
        
        cost[s]=0;
        turn[s]=start_turn%L;
        
        priority_queue<pii,vector<pii>,greater<pii>> pq;
        pq.push({0,s});
        
        while(!pq.empty()){
            
            auto [d,x]=pq.top();
            pq.pop();
            
            if(cost[x]!=d) continue;
            
            int ty=(turn[x]+1)%L;
            
            for(auto y:G[x]){
                if(y==-1) continue;
                if(goal_ng&&y==Goal) continue;
                if(chmin(cost[y],cost[x]+grid_damage[y][ty])){
                    pq.push({cost[y],y});
                    pre[y]=x;
                    turn[y]=ty;
                }
            }
        }
        
        return {cost,pre};
    }
    
    vector<int> get_tour(int s,int g,const auto &pre){
        
        assert(pre[g]!=-1);
        
        vector<int> ret;
        
        int x=g;
            
        while(x!=s){
            ret.push_back(x);
            int y=pre[x];
            x=y;
        }
        
        reverse(all(ret));
        
        return ret;
    }
    
    void solve(){
        
        rep(i,N*N) grid_damage[i].fill(1);
        
        rep(m,M){
            rep(k,4){
                int p=P[m];
                while(p!=-1){
                    p=G[p][k];
                    if(p!=-1){
                        for(int t=0;t<L;t+=K[m]){
                            grid_damage[p][t]+=D;
                        }
                    }
                }
            }
        }
        
        
        
        int s=Start;
        
        int cost_sum=0;
        
        vector<int> tour;
        
        array<bool,N*N> vis;
        
        vis.fill(false);
        
        bool have_key=false;
        
        vector<int> ans;
        
        while(true){
            
            auto [cost,pre]=dijkstra(s,len(tour),have_key);
            
            int x=-1;
            
            int min_cost=INF;
            
            rep(i,N*N){
                if(vis[i]) continue;
                if(S[i]=='J'&&chmin(min_cost,cost[i])) x=i;
            }
            
            if(H<cost_sum+min_cost) break;
            
            vector<int> now_tour=get_tour(s,x,pre);
            
            for(auto e:now_tour){
                vis[e]=true;
                tour.push_back(e);
                if(e==Key) have_key=true;
            }
            
            cost_sum+=min_cost;
            
            s=tour.back();
            
            
            vector<int> now_ans=tour;
            
            int ans_start=s,ans_cost=cost_sum;
            
            if(!have_key){
                auto [key_cost,key_pre]=dijkstra(s,len(tour),false);
                add(now_ans,get_tour(s,Key,key_pre));
                ans_start=Key;
                ans_cost+=key_cost[Key];
            }
            
            auto [goal_cost,goal_pre]=dijkstra(ans_start,len(now_ans),false);
            add(now_ans,get_tour(ans_start,Goal,goal_pre));
            ans_cost+=goal_cost[Goal];
            if(ans_cost<H){
                ans=now_ans;
            }
            
        }
        
        
        int x=Start;
        
        
        for(auto p:ans){
            int t=-1;
            rep(k,5){
                if(G[x][k]==p) t=k;
            }
            assert(t!=-1);
            if(t==4) cout << "S\n";
            else cout << "M " << UDLR[t] << '\n';
            
            x=p;
        }
        
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Timer::program_start_snap();
    
    int n,h;
    
    cin >> n >> D >> h;
    
    rep(i,N){
        string s;
        cin >> s;
        S+=s;
    }
    
    cin >> M;
    
    P.resize(M);
    K.resize(M);
    
    rep(i,M){
        int y,x;
        cin >> y >> x >> K[i];
        P[i]=one(y,x);
    }
    
    vector<int> pi={-1,1,0,0,0},pj={0,0,-1,1,0};
    
    rep(i,N){
        rep(j,N){
            G[one(i,j)].fill(-1);
            
            //if(S[one(i,j)]=='#'||S[one(i,j)]=='E') continue;
            
            rep(k,5){
                int ti=i+pi[k],tj=j+pj[k];
                if(ti<0||N<=ti||tj<0||N<=tj) continue;
                if(S[one(ti,tj)]=='#'||S[one(ti,tj)]=='E') continue;
                G[one(i,j)][k]=one(ti,tj);
            }
        }
    }
    
    rep(i,N*N){
        if(S[i]=='S') Start=i;
        if(S[i]=='K') Key=i;
        if(S[i]=='G') Goal=i;
    }

    Solver::solve();
    exit(0);
}
0