#include #include #include #include #include #include #include const int INF = 1e9; struct State { int r, c, key; }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int H, W, M; std::cin >> H >> W >> M; std::vector grid(H); int start_r, start_c, goal_r, goal_c; for (int i = 0; i < H; ++i) { std::cin >> grid[i]; for (int j = 0; j < W; ++j) { if (grid[i][j] == 'S') { start_r = i; start_c = j; } if (grid[i][j] == 'G') { goal_r = i; goal_c = j; } } } std::vector>> dist(H, std::vector>(W, std::vector(M + 1, INF))); std::queue q; dist[start_r][start_c][0] = 0; q.push({start_r, start_c, 0}); int dr[] = {-1, 1, 0, 0}; int dc[] = {0, 0, -1, 1}; while (!q.empty()) { auto [r, c, key] = q.front(); q.pop(); if (dist[r][c][key] > dist[r][c][key]) continue; // 既に短い経路が見つかっている for (int i = 0; i < 4; ++i) { int nr = r + dr[i]; int nc = c + dc[i]; if (nr < 0 || nr >= H || nc < 0 || nc >= W || grid[nr][nc] == '#') continue; char cell = grid[nr][nc]; // 扉のチェック if (islower(cell) && (cell - 'a' + 1) != key) continue; // 次の鍵の状態 int next_key = key; if (isdigit(cell)) { next_key = cell - '0'; } if (dist[r][c][key] + 1 < dist[nr][nc][next_key]) { dist[nr][nc][next_key] = dist[r][c][key] + 1; q.push({nr, nc, next_key}); } } } int ans = INF; for (int k = 0; k <= M; ++k) { ans = std::min(ans, dist[goal_r][goal_c][k]); } if (ans == INF) std::cout << -1 << std::endl; else std::cout << ans << std::endl; return 0; }