二次元グリッド上で、マス の上下左右のマスがなんであるかを学ぶ問題!
問題概要
の二次元グリッドが与えられる。グリッドの各マスは '.'(通路)または '#'(壁)である。
はじめ高橋くんはマス にいる。これから高橋君に 回の命令がくだる(サイズ の文字列 として与えられる)。
- 文字 'U' ならば、上のマスに移動する(壁またはグリッド外の場合は移動しない)
- 文字 'D' ならば、下のマスに移動する(壁またはグリッド外の場合は移動しない)
- 文字 'L' ならば、左のマスに移動する(壁またはグリッド外の場合は移動しない)
- 文字 'R' ならば、右のマスに移動する(壁またはグリッド外の場合は移動しない)
最終的に高橋くんのいるマスを答えよ。
制約
考えたこと
グリッドにおいて、上から 行目、左から 列目のマスを としましょう(一番上の行を 0 行目、一番左の列を 0 列目とします)。このとき、
- マス の上のマスは、
- マス の下のマスは、
- マス の左のマスは、
- マス の右のマスは、
このことを利用してシミュレーションしましょう。ただし、
- グリッドの外部に出てしまうような移動である場合は、スキップしましょう
- 移動先のマスが壁マスである場合も、スキップしましょう
以上の処理を実装すると、次のコードのようになります。
コード
#include <bits/stdc++.h> using namespace std; int main() { int H, W, x, y; cin >> H >> W >> x >> y; --x, --y; // 0-indexed にする vector<string> C(H); for (int i = 0; i < H; i++) cin >> C[i]; string X; cin >> X; for (auto c : X) { int x2 = x, y2 = y; if (c == 'U') --x2; else if (c == 'D') ++x2; else if (c == 'L') --y2; else ++y2; // 場外の場合はスキップ if (x2 < 0 || x2 >= H || y2 < 0 || y2 >= W || C[x2][y2] == '#') continue; // 壁マスの場合はスキップ if (C[x2][y2] == '#') continue; // 移動成立の場合は現在マスを更新 x = x2, y = y2; } cout << x+1 << " " << y+1 << endl; }