#include using namespace std; using pii=pair; using tii=tuple; using qii=tuple; 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 inline bool chmin(T &a,T b){ if(a>b){ a=b; return true; } return false; } template inline bool chmax(T &a,T b){ if(a inline bool chmin_ref(T &a,const T &b){ if(a>b){ a=b; return true; } return false; } template inline bool chmax_ref(T &a,const T &b){ if(a(now-start).count(); return ms; } int get_ms_all_program(){ auto now=chrono::steady_clock::now(); int ms=chrono::duration_cast(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 T get_random_element(const vector &v){ assert(!v.empty()); return v[rand_int(len(v))]; } template void add(vector &a,vector 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 P,K; array,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,N*N> grid_damage; pair,array> dijkstra(int s,int start_turn,bool goal_ng){ array cost,turn; array pre; cost.fill(INF); turn.fill(-1); pre.fill(-1); cost[s]=0; turn[s]=start_turn%L; priority_queue,greater> 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 get_tour(int s,int g,const auto &pre){ assert(pre[g]!=-1); vector 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 tour; array vis; vis.fill(false); bool have_key=false; vector 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 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 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> 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 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); }