[BOJ]破壁移動(no.206)
質問する
N×Mのマトリックス表現のマッピングがあります.地図では、0は移動可能な位置、1は移動不可能な壁の位置を示す.(1,1)から(N,M)の位置に移動し、最短経路に移動します.最短パスとは、地図上の最小セルを通るパスで、開始セルと終了セルが含まれます.
移動中に壁を割ったり移動したりする経路がもっと短い場合は、壁を割って移動することができます.
1つのセルで移動できるセルは上下左右に隣接するセルです.
地図を指定すると、最短パスを解くプログラムが作成されます.
入力
第1行はN(1≦N≦1000),M(1≦M≦1000)を与える.次のN行はMの数字で地図を与えます.(1,1)と(N,M)は常に0であると仮定する.
しゅつりょく
1行目に最短距離を出力します.不可能な場合は-1を出力します.
ちょっと辛いです.
🤔 の意見を打診
壁にぶつかった場合を解決すれば、一般的なbfs問題と同じです.
どんな壁を破壊して最短経路を変えるのか...壊していない方が早い場合もあります.
すべての壁をパラメータとしてbfsを迂回すべきではないでしょうか.答えは出てくるけど、歳月よ、君の月牙の果てに出てくる答えは意味がない.
破壊壁のパスをグラフィックを構成するブランチとして作成したらどうなりますか?
では、壁に出会うたびに、まず割って、それから一度壁を割った事実を覚え続けて、外に出ればいいのではないでしょうか.(ブランチの概念をもう1つ作成)
すべての壁が一度作られます
bfsだから先に着いた人はきっと最短経路ええ、いいですか.これでいいみたい??
そこで、下ののりで、3トンくらいのところに松露を作りました.
📌 説明する
ほどけたけどメモリを食べすぎたような気がする.
いくつかのグリディを反映しています.(壁が破れていない場合は、最初にアクセスします.そうでない場合は開きません)
アクセスリストも単純にアクセスを表示しているだけなので太ってしまいました.true/falseにアクセスするのではなく、壁を破壊するかどうかを値として保存することで、リスト次元を減らします.(もちろん、初期化状態は、アクセスするかどうかを判断するために個別の値で区別する必要があります.)
に注意
上記のグリンディは、優先度が明確な場合にのみ適用されるべきである.
そこで,改良後の解答を以下に示す.
📌 最終的なソリューション図ノードは地図情報しか含まれないという偏見を捨てましょう.特殊条件により分岐してもよい.
N×Mのマトリックス表現のマッピングがあります.地図では、0は移動可能な位置、1は移動不可能な壁の位置を示す.(1,1)から(N,M)の位置に移動し、最短経路に移動します.最短パスとは、地図上の最小セルを通るパスで、開始セルと終了セルが含まれます.
移動中に壁を割ったり移動したりする経路がもっと短い場合は、壁を割って移動することができます.
1つのセルで移動できるセルは上下左右に隣接するセルです.
地図を指定すると、最短パスを解くプログラムが作成されます.
入力
第1行はN(1≦N≦1000),M(1≦M≦1000)を与える.次のN行はMの数字で地図を与えます.(1,1)と(N,M)は常に0であると仮定する.
しゅつりょく
1行目に最短距離を出力します.不可能な場合は-1を出力します.
ちょっと辛いです.
🤔 の意見を打診
壁にぶつかった場合を解決すれば、一般的なbfs問題と同じです.
どんな壁を破壊して最短経路を変えるのか...壊していない方が早い場合もあります.
すべての壁をパラメータとしてbfsを迂回すべきではないでしょうか.答えは出てくるけど、歳月よ、君の月牙の果てに出てくる答えは意味がない.
破壊壁のパスをグラフィックを構成するブランチとして作成したらどうなりますか?
では、壁に出会うたびに、まず割って、それから一度壁を割った事実を覚え続けて、外に出ればいいのではないでしょうか.(ブランチの概念をもう1つ作成)
すべての壁が一度作られます
bfsだから先に着いた人はきっと最短経路ええ、いいですか.これでいいみたい??
📌 説明する
import sys
input = sys.stdin.readline
print = sys.stdout.write
def main():
n, m = map(int, input().split())
grid = tuple(tuple(map(int, input().rstrip())) for _ in range(n))
dx, dy = [1,-1,0,0], [0,0,1,-1]
def bfs():
visited = [[[False]*m for _ in range(n)] for _ in range(2)]
q = [(0,0,False)]
visited[0][0][0] = True
dist = 1
while q:
tmp = []
for x,y,broken in q:
if x == n-1 and y == m-1: return dist
for i in range(4):
nx, ny = x+dx[i], y+dy[i]
if 0 <= nx <n and 0 <= ny <m:
if grid[nx][ny] == 1 and not broken:
visited[0][nx][ny] = True
tmp.append((nx,ny,True))
elif grid[nx][ny] == 0 and not visited[broken][nx][ny]:
visited[broken][nx][ny] = True
tmp.append((nx,ny,broken))
q = tmp
dist += 1
return -1
print("%d" % bfs())
if __name__ == "__main__":
sys.exit(main())
ほどけたけどメモリを食べすぎたような気がする.
いくつかのグリディを反映しています.(壁が破れていない場合は、最初にアクセスします.そうでない場合は開きません)
アクセスリストも単純にアクセスを表示しているだけなので太ってしまいました.true/falseにアクセスするのではなく、壁を破壊するかどうかを値として保存することで、リスト次元を減らします.(もちろん、初期化状態は、アクセスするかどうかを判断するために個別の値で区別する必要があります.)
上記のグリンディは、優先度が明確な場合にのみ適用されるべきである.
そこで,改良後の解答を以下に示す.
📌 最終的なソリューション
import sys
input = sys.stdin.readline
def main():
n, m = map(int, input().split())
grid = tuple(input().rstrip() for _ in range(n))
dx, dy = [1,-1,0,0], [0,0,1,-1]
def bfs():
cache = [[2]*m for _ in range(n)] # 0-벽안뚫음, 1-벽뚫음, 2-초기화(미방문 상태)
q = [(0,0,0)]
cache[0][0] = 0
dist = 1
while q:
tmp = []
for x,y,chance in q:
if x == n-1 and y == m-1: return dist
for i in range(4):
nx, ny = x+dx[i], y+dy[i]
if 0 <= nx <n and 0 <= ny <m:
if cache[nx][ny] > chance:
if grid[nx][ny] == '1' and chance != 1:
cache[nx][ny] = 1
tmp.append((nx,ny,1))
elif grid[nx][ny] == '0':
cache[nx][ny] = chance
tmp.append((nx,ny,chance))
q = tmp
dist += 1
return -1
print(bfs())
if __name__ == "__main__":
sys.exit(main())
レビューReference
この問題について([BOJ]破壁移動(no.206)), 我々は、より多くの情報をここで見つけました https://velog.io/@wisepine/BOJ-벽-부수고-이동하기-no.2206テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol