Problem:
Problem C: Changing Grids
Background
A君とB君は、『Changing Grids』というゲームに熱中している。このゲームは2人用で、プレイヤー1がステージを構成し、プレイヤー2がそのステージに挑戦しゴールを目指すというものである。
今、A君とB君はこのゲームを何度かプレイしているが、A君の連勝でB君は1度も勝つことができていない。そこであなたは、B君にこのゲームを攻略するためのヒントを教えてあげることにした。
Problem
時刻
T
0
= 0における縦
H
×横
W
の大きさの二次元グリッドの状態が
Area
0
として与えられる。次に、このグリッドの状態は時刻
T
i
において、状態
Area
i
に切り替わる。この切り替わる過程は
N
回繰り返される。初期状態のグリッドにはスタートの位置'S'とゴールの位置'G'が与えられる。いずれかのグリッドにおいてゴールへ辿り着ける場合は、そのときの最小歩数を出力し、ゴールへ辿り着けない場合は、'-1'を出力せよ。なお、以下の条件も満たす必要がある。
Area
i
は以下の要素で構成されている。
‘.’は何もなく移動可能なマス
’#’は障害物であり、移動不可能なマス
'S'はスタート位置を表すマス
'G'はゴール位置を表すマス
プレイヤーは現在いるマスの隣接している上下左右のいずれか1マスに移動する、または現在いるマスに留まるのに1秒かかる。ただし、障害物のマスやグリッドの範囲外には移動できない。
歩数は、現在プレイヤーがいるマスから上下左右のマスへ1マス進むと1増加する。その場に留まる場合には増加しない。
全てのグリッドの大きさは縦
H
×横
W
である。
1マス移動、またはその場に留まった後にグリッドが切り替わる際、次のグリッドにおいて障害物が存在しないマスであれば今のグリッドの状態に関わらず移動が可能である。
全てのグリッドにおいて、初期のグリッドに与えられたゴール位置に到達した場合ゴールとみなす。
Input
入力は以下の形式で与えられる。
H
W
Area
0
N
T
1
Area
1
T
2
Area
2
.
.
T
N
Area
N
1行目に2つの整数
H,W
が空白区切りで与えられる。これは、それぞれ二次元グリッドの縦と横の大きさを表す。2行目から
H
+1行目までの各行に初期状態の二次元グリッドの状態が与えられる。
H
+2行目に整数
N
が与えられる。これは、二次元グリッドの変化する回数を表す。
H
+3行目以降に
N
個の二次元グリッドの切り替わる時刻
T
i
とその状態が与えられる。ただし、
T
i
は全て整数である。
Constraints
入力は以下の条件を満たす。
2 ≤
H,W
≤ 20
1 ≤
N
≤ 15
1 ≤
T
i
≤ 200 (
T
1
<
T
2
< ... <
T
N
)
スタート位置'S'とゴール位置'G'はそれぞれ初期の二次元グリッドに1つだけ存在する。
Output
スタートからゴールへ到達するための最小の歩数を出力せよ。ただし、ゴールに到達できない場合は'-1'を出力せよ。
Sample Input 1
2 2
S.
.G
1
3
##
##
Sample Output 1
2
1番目のグリッドに切り替わる時刻
T
1
は3であり、時間内にプレイヤーはスタートからゴールまでの最短歩数が2歩で辿り着くことが可能なので2を出力する。
Sample Input 2
2 2
S.
.G
1
2
##
##
Sample Output 2
-1
Sample Input 3
2 3
S##
##G
4
2
###
.##
3
###
#.#
5
###
##.
7
###
###
Sample Output 3
3
Sample Input 4
4 3
S..
...
.G.
...
4
2
###
#.#
###
#.#
4
###
#..
#..
###
6
###
#.#
###
#..
8
###
#..
#..
###
Sample Output 4
3
Sample Input 5
3 3
S##
###
##G
1
1
...
...
...
Sample Output 5
4

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repl(i,0,n)
#define dbg(x) cout<<#x<<"="<<x<<endl

#define INF INT_MAX/3

struct state{
  int i,j,t,d;
};
bool operator<(const state& a,const state& b){
  return a.d > b.d;
}

int di[]={-1,0,1,0,0};
int dj[]={0,-1,0,1,0};

int H,W,N;
vector<vector<string> > bs;
int si,sj,ti,tj;
int dist[22][22][201];

bool can(int t,int i,int j){
  if(bs[t][i][j]!='#')return true;
  else return false;
}

int main(){
  cin>>H>>W;
  bs.resize(201);

  int pret=0;
  vector<string> preb(H);
  rep(j,H)cin>>preb[j];
  rep(i,H)rep(j,W){
    if(preb[i][j]=='S'){
      si=i; sj=j;
    }
    if(preb[i][j]=='G'){
      ti=i; tj=j;
    }
  }

  cin>>N;
  rep(i,N){
    int T;
    vector<string> input(H);
    cin>>T;
    rep(j,H)cin>>input[j];
    repl(j,pret,T){
      bs[j]=preb;
    }
    preb=input;
    pret=T;
  }
  repl(j,pret,201)bs[j]=preb;

  rep(i,H)rep(j,W)rep(t,201)dist[i][j][t]=INF;
  priority_queue<state> que;
  que.push((state){si,sj,0,0});
  while(que.size()){
    state s=que.top(); que.pop();
    if(dist[s.i][s.j][s.t]!=INF)continue;
    dist[s.i][s.j][s.t]=s.d;
    if(s.i==ti&&s.j==tj){
      cout<<dist[s.i][s.j][s.t]<<endl;
      return 0;
    }
    rep(dir,5){
      int ni=s.i+di[dir],nj=s.j+dj[dir],nt=min(200,s.t+1);

      if(ni<0||ni>=H||nj<0||nj>=W||!can(nt,ni,nj))continue;

      {
        if(dir==4) que.push((state){ni,nj,nt,s.d});
        else que.push((state){ni,nj,nt,s.d+1});
      }
    }
  }
  cout<<-1<<endl;

}
accuracy: 1
time_ms: 10
memory_kb: 3876
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=a;i<b;++i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()

typedef long long lint;
typedef pair<int, int> pii;

struct State {
	int x, y, t, step;
	State(int _x, int _y, int _t, int _step) : x(_x), y(_y), t(_t), step(_step) {}
};
bool operator > (const State& a, const State& b) { return a.step > b.step; }

int H, W, N, T[20];
string grid[20][25];
int steps[20][25][25];
int sx, sy, gx, gy;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};

void solve() {
	string last_g = "";
	for_(i,0,W) last_g += "#";
	for_(i,0,H) grid[N + 1][i] = last_g;
	T[0] = 0; T[N + 1] = 1000;
	for_(i,0,20) for_(j,0,25) fill(steps[i][j], steps[i][j] + 25, (int)1e9);
	steps[0][sy][sx] = 0;
	
	for_(i,0, N + 1) {
		int limit = T[i + 1] - T[i];
		
		priority_queue<State, vector<State>, greater<State> > q;
		for_(y,0,H) for_(x,0,W) {
			if (steps[i][y][x] < (int)1e9) q.push(State(x, y, 0, steps[i][y][x]));
		}
		
		while (!q.empty()) {
			State s = q.top(); q.pop();
			
			int cx = s.x, cy = s.y, t = s.t, step = s.step;
			
			if (cx == gx && cy == gy) {
				cout << step << endl;
				return;
			}
			
			if (t >= limit) continue;
			
			if (t < limit - 1 && steps[i][cy][cx] >= step) {
				steps[i][cy][cx] = step;
				q.push(State(cx, cy, t + 1, step));
			}
			
			if (t == limit - 1 && grid[i + 1][cy][cx] != '#' && steps[i + 1][cy][cx] > step) {
				steps[i + 1][cy][cx] = step;
			} 
			
			for_(d,0,4) {
				int nx = cx + dx[d], ny = cy + dy[d];
				if (!(0 <= nx && nx < W && 0 <= ny && ny < H)) continue;
				
				if (t < limit - 1 && grid[i][ny][nx] == '#') continue;				
				if (t < limit - 1 && steps[i][ny][nx] > step + 1) {
					steps[i][ny][nx] = step + 1;
					q.push(State(nx, ny, t + 1, step + 1));
				}
				
				if (t == limit - 1 && grid[i + 1][ny][nx] == '#') continue;
				if (t == limit - 1 && steps[i + 1][ny][nx] > step + 1) {
					steps[i + 1][ny][nx] = step + 1;
				}
			}
		}
	}
	
	cout << -1 << endl;
}

int main() {
	cin >> H >> W;
	for_(i,0,H) {
		cin >> grid[0][i];
		for_(j,0,W) {
			if (grid[0][i][j] == 'S') {
				sx = j; sy = i;
			}
			if (grid[0][i][j] == 'G') {
				gx = j; gy = i;
			}
		}
	}
	cin >> N;
	for_(i,1,N + 1) {
		cin >> T[i];
		for_(j,0,H) cin >> grid[i][j];
	}
	solve();
	return 0;
}
accuracy: 0.8387096774193549
time_ms: 10
memory_kb: 1292
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=a;i<b;++i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()

typedef long long lint;
typedef pair<int, int> pii;

struct State {
	int x, y, t, step;
	State(int _x, int _y, int _t, int _step) : x(_x), y(_y), t(_t), step(_step) {}
};
bool operator > (const State& a, const State& b) { return a.step > b.step; }

int H, W, N, T[20];
string grid[20][25];
int steps[20][25][25];
int sx, sy, gx, gy;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};

void solve() {
	string last_g = "";
	for_(i,0,W) last_g += "#";
	for_(i,0,H) grid[N + 1][i] = last_g;
	T[0] = 0; T[N + 1] = 1000;
	for_(i,0,20) for_(j,0,25) fill(steps[i][j], steps[i][j] + 25, (int)1e9);
	steps[0][sy][sx] = 0;
	
	for_(i,0, N + 1) {
		int limit = T[i + 1] - T[i];
		
		priority_queue<State, vector<State>, greater<State> > q;
		for_(y,0,H) for_(x,0,W) {
			if (steps[i][y][x] < (int)1e9) q.push(State(x, y, 0, steps[i][y][x]));
		}
		
		while (!q.empty()) {
			State s = q.top(); q.pop();
			
			int cx = s.x, cy = s.y, t = s.t, step = s.step;
			
			if (cx == gx && cy == gy) {
				cout << step << endl;
				return;
			}
			
			if (t >= limit) continue;
			
			if (steps[i][cy][cx] >= step) {
				if (t < limit - 1 && steps[i][cy][cx] >= step) {
					steps[i][cy][cx] = step;
					q.push(State(cx, cy, t + 1, step));
				}
				
				if (t == limit - 1 && grid[i + 1][cy][cx] != '#' && steps[i + 1][cy][cx] > step) {
					steps[i + 1][cy][cx] = step;
				} 
			}
			
			for_(d,0,4) {
				int nx = cx + dx[d], ny = cy + dy[d];
				if (!(0 <= nx && nx < W && 0 <= ny && ny < H)) continue;
				
				if (t < limit - 1 && grid[i][ny][nx] == '#') continue;				
				if (t < limit - 1 && steps[i][ny][nx] > step + 1) {
					steps[i][ny][nx] = step + 1;
					q.push(State(nx, ny, t + 1, step + 1));
				}
				
				if (t == limit - 1 && grid[i + 1][ny][nx] == '#') continue;
				if (t == limit - 1 && steps[i + 1][ny][nx] > step + 1) {
					steps[i + 1][ny][nx] = step + 1;
				}
			}
		}
	}
	
	cout << -1 << endl;
}

int main() {
	cin >> H >> W;
	for_(i,0,H) {
		cin >> grid[0][i];
		for_(j,0,W) {
			if (grid[0][i][j] == 'S') {
				sx = j; sy = i;
			}
			if (grid[0][i][j] == 'G') {
				gx = j; gy = i;
			}
		}
	}
	cin >> N;
	for_(i,1,N + 1) {
		cin >> T[i];
		for_(j,0,H) cin >> grid[i][j];
	}
	solve();
	return 0;
}
accuracy: 0.8387096774193549
time_ms: 10
memory_kb: 1292
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=a;i<b;++i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()

typedef long long lint;
typedef pair<int, int> pii;

struct State {
	int x, y, t, step;
	State(int _x, int _y, int _t, int _step) : x(_x), y(_y), t(_t), step(_step) {}
};
bool operator > (const State& a, const State& b) { return a.step > b.step; }

int H, W, N, T[20];
string grid[20][25];
int steps[20][25][25];
int sx, sy, gx, gy;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};

void solve() {
	string last_g = "";
	for_(i,0,W) last_g += ".";
	for_(i,0,H) grid[N + 1][i] = last_g;
	T[0] = 0; T[N + 1] = 1000;
	for_(i,0,20) for_(j,0,25) fill(steps[i][j], steps[i][j] + 25, (int)1e9);
	steps[0][sy][sx] = 0;
	
	for_(i,0, N + 1) {
		int limit = T[i + 1] - T[i];
		
		priority_queue<State, vector<State>, greater<State> > q;
		for_(y,0,H) for_(x,0,W) {
			if (steps[i][y][x] < (int)1e9) q.push(State(x, y, 0, steps[i][y][x]));
		}
		
		while (!q.empty()) {
			State s = q.top(); q.pop();
			
			int cx = s.x, cy = s.y, t = s.t, step = s.step;
			
			if (cx == gx && cy == gy) {
				cout << step << endl;
				return;
			}
			
			if (t >= limit) continue;
			
			if (steps[i][cy][cx] >= step) {
				if (t < limit - 1 && steps[i][cy][cx] >= step) {
					steps[i][cy][cx] = step;
					q.push(State(cx, cy, t + 1, step));
				}
				
				if (t == limit - 1 && grid[i + 1][cy][cx] != '#' && steps[i + 1][cy][cx] > step) {
					steps[i + 1][cy][cx] = step;
				} 
			}
			
			for_(d,0,4) {
				int nx = cx + dx[d], ny = cy + dy[d];
				if (!(0 <= nx && nx < W && 0 <= ny && ny < H)) continue;
				
				if (t < limit - 1 && grid[i][ny][nx] == '#') continue;				
				if (t < limit - 1 && steps[i][ny][nx] > step + 1) {
					steps[i][ny][nx] = step + 1;
					q.push(State(nx, ny, t + 1, step + 1));
				}
				
				if (t == limit - 1 && grid[i + 1][ny][nx] == '#') continue;
				if (t == limit - 1 && steps[i + 1][ny][nx] > step + 1) {
					steps[i + 1][ny][nx] = step + 1;
				}
			}
		}
	}
	
	cout << -1 << endl;
}

int main() {
	cin >> H >> W;
	for_(i,0,H) {
		cin >> grid[0][i];
		for_(j,0,W) {
			if (grid[0][i][j] == 'S') {
				sx = j; sy = i;
			}
			if (grid[0][i][j] == 'G') {
				gx = j; gy = i;
			}
		}
	}
	cin >> N;
	for_(i,1,N + 1) {
		cin >> T[i];
		for_(j,0,H) cin >> grid[i][j];
	}
	solve();
	return 0;
}
accuracy: 0.8387096774193549
time_ms: 10
memory_kb: 1292
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=a;i<b;++i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()

typedef long long lint;
typedef pair<int, int> pii;

struct State {
	int x, y, t, step;
	State(int _x, int _y, int _t, int _step) : x(_x), y(_y), t(_t), step(_step) {}
};
bool operator > (const State& a, const State& b) { return a.step > b.step; }

int H, W, N, T[20];
string grid[20][25];
int steps[20][25][25];
int sx, sy, gx, gy;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};

void solve() {
	T[0] = 0; T[N + 1] = 1000;
	for_(i,0,20) for_(j,0,25) fill(steps[i][j], steps[i][j] + 25, (int)1e9);
	steps[0][sy][sx] = 0;
	
	for_(i,0, N + 1) {
		int limit = T[i + 1] - T[i];
		
		priority_queue<State, vector<State>, greater<State> > q;
		for_(y,0,H) for_(x,0,W) {
			if (steps[i][y][x] < (int)1e9) q.push(State(x, y, 0, steps[i][y][x]));
		}
		
		while (!q.empty()) {
			State s = q.top(); q.pop();
			
			int cx = s.x, cy = s.y, t = s.t, step = s.step;
			
			if (cx == gx && cy == gy) {
				cout << step << endl;
				return;
			}
			
			if (t >= limit) continue;
			
			if (steps[i][cy][cx] >= step) {
				if (t < limit - 1 && steps[i][cy][cx] >= step) {
					steps[i][cy][cx] = step;
					q.push(State(cx, cy, t + 1, step));
				}
				
				if (t == limit - 1 && grid[i + 1][cy][cx] != '#' && steps[i + 1][cy][cx] > step) {
					steps[i + 1][cy][cx] = step;
				} 
			}
			
			for_(d,0,4) {
				int nx = cx + dx[d], ny = cy + dy[d];
				if (!(0 <= nx && nx < W && 0 <= ny && ny < H)) continue;
				
				if (t < limit - 1 && grid[i][ny][nx] == '#') continue;				
				if (t < limit - 1 && steps[i][ny][nx] > step + 1) {
					steps[i][ny][nx] = step + 1;
					q.push(State(nx, ny, t + 1, step + 1));
				}
				
				if (t == limit - 1 && grid[i + 1][ny][nx] == '#') continue;
				if (t == limit - 1 && steps[i + 1][ny][nx] > step + 1) {
					steps[i + 1][ny][nx] = step + 1;
				}
			}
		}
	}
	
	cout << -1 << endl;
}

int main() {
	cin >> H >> W;
	for_(i,0,H) {
		cin >> grid[0][i];
		for_(j,0,W) {
			if (grid[0][i][j] == 'S') {
				sx = j; sy = i;
			}
			if (grid[0][i][j] == 'G') {
				gx = j; gy = i;
			}
		}
	}
	cin >> N;
	for_(i,1,N + 1) {
		cin >> T[i];
		for_(j,0,H) cin >> grid[i][j];
	}
	solve();
	return 0;
}
accuracy: 0.8387096774193549
time_ms: 10
memory_kb: 1284
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=a;i<b;++i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()

typedef long long lint;
typedef pair<int, int> pii;

struct State {
	int x, y, t, step;
	State(int _x, int _y, int _t, int _step) : x(_x), y(_y), t(_t), step(_step) {}
};
bool operator > (const State& a, const State& b) { return a.step > b.step; }

int H, W, N, T[20];
string grid[20][25];
int steps[20][25][25];
int sx, sy, gx, gy;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};

void solve() {
	T[0] = 0; T[N + 1] = 1000;
	for_(i,0,20) for_(j,0,25) fill(steps[i][j], steps[i][j] + 25, (int)1e9);
	steps[0][sy][sx] = 0;
	
	for_(i,0, N + 1) {
		int limit = T[i + 1] - T[i];
		
		priority_queue<State, vector<State>, greater<State> > q;
		for_(y,0,H) for_(x,0,W) {
			if (steps[i][y][x] < (int)1e9) q.push(State(x, y, 0, steps[i][y][x]));
		}
		
		while (!q.empty()) {
			State s = q.top(); q.pop();
			
			int cx = s.x, cy = s.y, t = s.t, step = s.step;
			if (t >= limit) continue;
			
			if (steps[i][cy][cx] >= step) {
				if (t < limit - 1 && steps[i][cy][cx] >= step) {
					steps[i][cy][cx] = step;
					q.push(State(cx, cy, t + 1, step));
				}
				
				if (t == limit - 1 && grid[i + 1][cy][cx] != '#' && steps[i + 1][cy][cx] > step) {
					steps[i + 1][cy][cx] = step;
				} 
			}
			
			for_(d,0,4) {
				int nx = cx + dx[d], ny = cy + dy[d];
				if (!(0 <= nx && nx < W && 0 <= ny && ny < H)) continue;
				
				if (t < limit - 1 && grid[i][ny][nx] == '#') continue;				
				if (t < limit - 1 && steps[i][ny][nx] > step + 1) {
					steps[i][ny][nx] = step + 1;
					q.push(State(nx, ny, t + 1, step + 1));
				}
				
				if (t == limit - 1 && grid[i + 1][ny][nx] == '#') continue;
				if (t == limit - 1 && steps[i + 1][ny][nx] > step + 1) {
					steps[i + 1][ny][nx] = step + 1;
				}
			}
		}
	}
	
	int ans = (int)1e9;
	for_(i,0,N + 1) ans = min(ans, steps[i][gy][gx]);
	if (ans == (int)1e9) cout << -1 << endl;
	else cout << ans << endl;
}

int main() {
	cin >> H >> W;
	for_(i,0,H) {
		cin >> grid[0][i];
		for_(j,0,W) {
			if (grid[0][i][j] == 'S') {
				sx = j; sy = i;
			}
			if (grid[0][i][j] == 'G') {
				gx = j; gy = i;
			}
		}
	}
	cin >> N;
	for_(i,1,N + 1) {
		cin >> T[i];
		for_(j,0,H) cin >> grid[i][j];
	}
	solve();
	return 0;
}
accuracy: 0.8387096774193549
time_ms: 10
memory_kb: 1284
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
#define tpl(...) make_tuple(__VA_ARGS__)
const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef long long ll;
typedef pair<int,int> pii;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T>ostream&operator<<(ostream &o,const vector<T>&t){o<<'[';FOR(i,t){if(i!=t.begin())o<<',';o<<*i;}return o<<']';}
template<class S,class T>ostream&operator<<(ostream &o,const pair<S,T>&t){return o<<'('<<t.first<<','<<t.second<<')';}
template<int N,class Tp>void output(ostream&,const Tp&){}
template<int N,class Tp,class,class ...Ts>void output(ostream &o,const Tp&t){if(N)o<<',';o<<get<N>(t);output<N+1,Tp,Ts...>(o,t);}
template<class ...Ts>ostream&operator<<(ostream&o,const tuple<Ts...>&t){o<<'(';output<0,tuple<Ts...>,Ts...>(o,t);return o<<')';}
template<class T>void output(T t,char z=10){if(t<0)t=-t,putchar(45);int c[20];
int k=0;while(t)c[k++]=t%10,t/=10;for(k||(c[k++]=0);k;)putchar(c[--k]^48);putchar(z);}
template<class T>void outputs(T t){output(t);}
template<class S,class ...T>void outputs(S a,T...t){output(a,32);outputs(t...);}
template<class T>void output(T *a,int n){REP(i,n)output(a[i],i!=n-1?',':10);}
template<class T>void output(T *a,int n,int m){REP(i,n)output(a[i],m);}
template<class T>bool input(T &t){int n=1,c;for(t=0;!isdigit(c=getchar())&&~c&&c-45;);
if(!~c)return 0;for(c-45&&(n=0,t=c^48);isdigit(c=getchar());)t=10*t+c-48;t=n?-t:t;return 1;}
template<class S,class ...T>bool input(S&a,T&...t){input(a);return input(t...);}

const int H = 20;
const int W = 20;

const int dy[] = {-1,0,1,0,0};
const int dx[] = {0,1,0,-1,0};

struct P {
  int y,x,t;
  int d;
  bool operator<(const P &rhs) const {
    return d > rhs.d;
  }
};
struct Field {
  char a[801][H][W];
  int h,w;
  int sy,sx;
  int dist[801][H][W];
  bool input_hw() {
    return input(h,w);
  }
  void set_hw(int _h, int _w) {
    h = _h; w = _w;
  }
  void in() {
    REP(i,h)REP(j,w) {
      cin>>a[0][i][j];
      if (a[0][i][j] == 'S') {
        sy = i;
        sx = j;
      }
    }
    int n;
    cin >> n;
    int pre = 0;
    REP(k,n) {
      int t;
      cin >> t;
      for (int s=pre+1; s<t; ++s) {
        REP(i,h)REP(j,w) {
          a[s][i][j] = a[pre][i][j];
        }
      }
      REP(i,h) {
        REP(j,w) {
          cin >> a[t][i][j];
        }
      }
      pre = t;
    }
    for (int s=pre+1; s<=800; ++s) {
      REP(i,h)REP(j,w) {
        a[s][i][j] = a[pre][i][j];
      }
    }    
  }
  int bfs() {
    memset(dist,0x3f,sizeof(dist));
    priority_queue<P> Q;
    Q.push(P{sy,sx,0,0});
    dist[0][sy][sx] = 0;
    while(!Q.empty()) {
      P p = Q.top(); Q.pop();
      int y = p.y;
      int x = p.x;
      if (dist[p.t][y][x] < p.d) continue;
      if (a[0][y][x] == 'G') return dist[p.t][y][x];
      if (p.t == 800) continue;
      // outputs(p.t,y,x, dist[p.t][y][x]);
      REP(i,5) {
        int yy = y + dy[i];
        int xx = x + dx[i];
        char c = a[p.t+1][yy][xx];
        if (valid(yy,xx,h,w) && c != '#') {
          int d2 = dist[p.t][y][x] + (i<4);
          if (dist[p.t+1][yy][xx] > d2) {
            dist[p.t+1][yy][xx] = d2;
            Q.push(P{yy,xx,p.t+1,d2});
          }          
        }            
      }
    }
    return -1;
  }
} field;

int main() {
  while(field.input_hw()) {
    field.in();
    cout << field.bfs() << endl;
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3108
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <climits>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE 

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef pair<int, int> P;
typedef long long ll;

const int N = 1e5 + 10;

vector<int> G[N];

struct state{
	int r, c, t, d;
	bool operator < (const state &rhs) const{
		return d > rhs.d;
	}
};

int dist[25][25][210];

int dx[] = { 0, 1, 0, -1, 0 };
int dy[] = { -1, 0, 1, 0, 0 };

inline int &getdist(state &s){
	return dist[s.r][s.c][s.t];
}

void go(state nxt, priority_queue<state> &q){
	int &d = getdist(nxt);
	if (d <= nxt.d) return;
	d = nxt.d;
	q.push(nxt);
}

int a[210];

int main(){
	int h, w;
	cin >> h >> w;
	vector<string> tmp(h);
	rep(i, h) cin >> tmp[i];
	int n;
	cin >> n;
	vector<vector<string>> area(n+1, vector<string>(h));
	area[0] = tmp;

	MEMSET(a, -1);
	a[0] = 0;
	FOR(i, 1, n + 1){
		int x;
		cin >> x;
		a[x] = i;
		rep(j, h) cin >> area[i][j];
	}
	rep(i, 200) if (a[i + 1] < 0) a[i + 1] = a[i];

	rep(i, 25) rep(j, 25) rep(k, 210) dist[i][j][k] = 1e9;

	P start, goal;
	rep(i, h) rep(j, w){
		if (tmp[i][j] == 'S') start = MP(i, j);
		if (tmp[i][j] == 'G') goal = MP(i, j);
	}

	priority_queue<state> q;
	go({ start.first, start.second, 0, 0 }, q);
	while (!q.empty()){
		auto s = q.top();
		q.pop();

		if (getdist(s) < s.d) continue;

		if (s.r == goal.first && s.c == goal.second){
			cout << s.d << endl;
			return 0;
		}

		s.t = min(s.t+1, 200);
		++s.d;
		rep(d, 5){
			state nxt = s;
			if (d == 4) --nxt.d;
			nxt.r += dx[d], nxt.c += dy[d];
			if (nxt.r < 0 || nxt.r >= h || nxt.c < 0 || nxt.c >= w) continue;
			int na = a[nxt.t];
			if (area[na][nxt.r][nxt.c] == '#') continue;
			go(nxt, q);
		}
	}
	cout << -1 << endl;

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4228
final_rank: 3

code_snippet: #include <iostream>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() {return val;}
    bool operator!=(Iterator &itr) {return val < itr.val;}
    void operator++() {++val;}
  };
  Iterator i, n;
public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator &begin() {return i;}
  Iterator &end() {return n;}
};

template<class T> T at(vector<T> v, int i) {return v[(i % (int)v.size() + v.size()) % v.size()];}

const int INF = 1e9;

const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

int main() {
  int h, w;
  cin >> h >> w;
  string area[16][h];
  for (int i : range(h)) cin >> area[0][i];
  int n;
  cin >> n;
  int t[n];
  for (int i : range(n)) {
    cin >> t[i];
    for (int j : range(h)) cin >> area[i + 1][j];
  }
  int dp[1000][h][w];
  for (int i : range(1000)) for (int j : range(h)) for (int k : range(w)) dp[i][j][k] = INF;
  for (int i : range(h)) for (int j : range(w)) if (area[0][i][j] == 'S') dp[0][i][j] = 0;
  int s = 0, res = INF;
  for (int i : range(999)) {
    if (s < n && t[s] == i + 1) ++s;
    for (int y : range(h)) for (int x : range(w)) if (dp[i][y][x] != INF) {
      for (int k : range(4)) {
        int yy = y + dy[k];
        int xx = x + dx[k];
        if (yy < 0 || h <= yy) continue;
        if (xx < 0 || w <= xx) continue;
        if (area[s][yy][xx] == '#') continue;
        dp[i + 1][yy][xx] = min(dp[i + 1][yy][xx], dp[i][y][x] + 1);
        if (area[0][yy][xx] == 'G') res = min(res, dp[i][y][x] + 1);
      }
      if (area[s][y][x] != '#') dp[i + 1][y][x] = min(dp[i + 1][y][x], dp[i][y][x]);
    }
  }
  if (res == INF) cout << -1 << endl;
  else cout << res << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 2796
final_rank: 1

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>
#include <fstream>
#include <bitset>

using namespace std;

#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
template <typename T> void print_container(ostream& os, const T& c) { const char* _s = " "; if (!c.empty()) { __typeof__(c.begin()) last = --c.end(); foreach (it, c) { os << *it; if (it != last) os << _s; } } }
template <typename T> ostream& operator<<(ostream& os, const vector<T>& c) { print_container(os, c); return os; }
template <typename T> ostream& operator<<(ostream& os, const set<T>& c) { print_container(os, c); return os; }
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& c) { print_container(os, c); return os; }
template <typename T> ostream& operator<<(ostream& os, const deque<T>& c) { print_container(os, c); return os; }
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& c) { print_container(os, c); return os; }
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) { os << "(" << p.first << ", " << p.second << ")"; return os; }

template <typename T> void print(T a, int n, const string& split = " ") { for (int i = 0; i < n; i++) { cout << a[i]; if (i + 1 != n) cout << split; } cout << endl; }
template <typename T> void print2d(T a, int w, int h, int width = -1, int br = 0) { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) { if (width != -1) cout.width(width); cout << a[i][j] << ' '; } cout << endl; } while (br--) cout << endl; }
template <typename T> void input(T& a, int n) { for (int i = 0; i < n; ++i) cin >> a[i]; }
#define dump(v) (cerr << #v << ": " << v << endl)

#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define erep(i, n) for (int i = 0; i <= (int)(n); ++i)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define clr(a, x) memset(a, x, sizeof(a))
#define sz(a) ((int)(a).size())
#define mp(a, b) make_pair(a, b)
#define ten(n) ((long long)(1e##n))

template <typename T, typename U> void upmin(T& a, const U& b) { a = min<T>(a, b); }
template <typename T, typename U> void upmax(T& a, const U& b) { a = max<T>(a, b); }
template <typename T> void uniq(T& a) { sort(a.begin(), a.end()); a.erase(unique(a.begin(), a.end()), a.end()); }
template <class T> string to_s(const T& a) { ostringstream os; os << a; return os.str(); }
template <class T> T to_T(const string& s) { istringstream is(s); T res; is >> res; return res; }
void fast_io() { cin.tie(0); ios::sync_with_stdio(false); }
bool in_rect(int x, int y, int w, int h) { return 0 <= x && x < w && 0 <= y && y < h; }

typedef long long ll;
typedef pair<int, int> pint;

const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };



int main()
{
    int h, w;
    cin >> h >> w;
    char c[36][36];
    rep(y, h)
        cin >> c[y];

    int n;
    cin >> n;
    int next_t;
    cin >> next_t;

    int sx = -1, sy, gx = -1, gy;
    rep(y, h) rep(x, w)
    {
        if (c[y][x] == 'S')
        {
            sx = x, sy = y;
            c[y][x] = '.';
        }
        else if (c[y][x] == 'G')
        {
            gx = x, gy = y;
            c[y][x] = '.';
        }
    }
    assert(sx != -1 && gx != -1);

    const int inf = ten(8);
    int dp[36][36];
    rep(y, h) rep(x, w)
        dp[y][x] = inf;
    dp[sy][sx] = 0;
    int stage = 0;
    int res = inf;
    rep(cur_t, ten(4))
    {
        if (stage < n && cur_t == next_t)
        {
            rep(y, h)
                cin >> c[y];
            cin >> next_t;
            ++stage;
        }

        int ndp[36][36];
        rep(y, h) rep(x, w)
        {
            ndp[y][x] = inf;
            if (c[y][x] == '#')
                dp[y][x] = inf;
        }
        if (dp[gy][gx] != inf)
            upmin(res, dp[gy][gx]);

        rep(y, h) rep(x, w)
        {
            if (dp[y][x] != inf)
            {
                upmin(ndp[y][x], dp[y][x]);
                rep(dir, 4)
                {
                    int nx = x + dx[dir], ny = y + dy[dir];
                    if (in_rect(nx, ny, w, h))
                        upmin(ndp[ny][nx], dp[y][x] + 1);
                }
            }
        }

        bool updated = false;
        rep(y, h) rep(x, w)
        {
            updated |= dp[y][x] != ndp[y][x];
            dp[y][x] = ndp[y][x];
        }
        if (!updated)
            break;
    }

    cout << (res != inf ? res : -1) << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 1176
final_rank: 3