NISHIO Hirokazu[Translate]
PAST3G
PAST3G
G
障害物のあるグリッドの上を将棋の金将がスタートからゴールまで移動するときの最短経路長を求める問題。
幅優先探索。障害物が置かれうる範囲の外側1マス用意すれば迂回経路には十分。
バグりやすそうなのでまずグリッドのサイズを5x5にしたバージョンでデバッグ出力しながらバグを潰した。
初回提出は訪問済みのマスに印をつけ忘れてタイムリミット超過。小さいデータでテストしてた時は気づかなかった。
2回目提出はランタイムエラー、グリッドサイズを1マス少なく計算してた。-1から1の範囲にマス目は3つある。

python
TINY_TEST = False if TINY_TEST: MIN_BOUND = -2 MAX_BOUND = 2 else: MIN_BOUND = -200 MAX_BOUND = 200 WIDTH = (MAX_BOUND - MIN_BOUND) + 4 # why not 3? M = [["."] * WIDTH for i in range(WIDTH)] def setMap(p, v): x, y = p M[y - MIN_BOUND + 1][x - MIN_BOUND + 1] = v def getMap(p): x, y = p return M[y - MIN_BOUND + 1][x - MIN_BOUND + 1] START = (0, 0) if TINY_TEST: GOAL = (2, 2) setMap(START, "S") setMap(GOAL, "G") obstacles = [(1, 1)] for p in obstacles: setMap(p, "#") else: N, X, Y = [int(x) for x in input().split()] setMap((X, Y), "G") for i in range(N): p = [int(x) for x in input().split()] setMap(p, "#") def pp(map): for line in map: print("".join(line)) def main(): def visit(x, y): if getMap((x, y)) == "G": return True if getMap((x, y)) != ".": return if x < MIN_BOUND-1 or MAX_BOUND+1 < x: return if y < MIN_BOUND-1 or MAX_BOUND+1 < y: return newFront.append((x, y)) setMap((x, y), "v") newFront = [START] for numSteps in range(1, 1000): front = set(newFront) # print("len front,", len(front), numSteps) # print(front) newFront = [] for x, y in front: isFinished = ( visit(x + 1, y + 1) or visit(x, y + 1) or visit(x - 1, y + 1) or visit(x + 1, y) or visit(x - 1, y) or visit(x, y - 1)) if isFinished: print(numSteps) return if not newFront: print(-1) return main()

"Engineer's way of creating knowledge" the English version of my book is now available on [Engineer's way of creating knowledge]

(C)NISHIO Hirokazu / Converted from [Scrapbox] at [Edit]