[伯俊2206]破壁後移動
23456 ワード
https://www.acmicpc.net/problem/2206
🥚質問する
壁を破った問題をどう表現しますか?
1つ目のアイデアは、「壁がまだ破れていない場合、壁が破壊されたことを示し、その点でbfsを再実行する」(時間の複雑さを考慮してコードを記述する必要がある) 回のアクセスを3 Dリストにまとめることで、破壁を表示できます. 訪問[r][c][0]:世界(r,c)から壁を破壊したことのない距離 アクセス[r][c][1]:世界(r,c)から一度壁を破壊した(r,c)移動距離 アクセス更新方法 arr[new r][new c]が0の場合 0に移動可能で、flagに限定されません. visited[new_r][new_c][flag]= visited[r][c][flag] + 1 arr[new r][new c]が1の場合 未破壁(flag=0)の場合、 を移動することができる. visited[new_r][new_c][1] = visited[r][c][0] + 1 flagを1に更新! (例)
2 2
01
10
(r,c)毎にbfsが出力されると、🔽
🥚質問する
🥚入力/出力
🍳コード#コード#
from collections import deque
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
arr = [list(map(int, list(input().strip()))) for _ in range(n)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 3차원 배열로 표현
# visited[r][c][0] -> 벽을 한 번도 안 뚫었을 때
# visited[r][c][1] -> 벽을 한번이라도 뚫었을 때
visited = [[[0] * 2 for _ in range(m)] for __ in range(n)]
# flag가 1일 때 -> 벽을 한 번이라도 뚫음
# flag가 0일 때 -> 벽을 한 번도 안 뚫음
def bfs(r, c, flag):
q = deque([])
q.append((r, c, flag))
visited[r][c][flag] = 1
while q:
r, c, flag = q.popleft()
"""
if flag == 0:
print("벽을 파괴하지 않은", end=' ')
else:
print("벽을 파괴한", end=' ')
print("(", r, ",", c, ")", "에서 탐색한 결과")
"""
for i in range(4):
new_r = r + dx[i]
new_c = c + dy[i]
if 0 <= new_r < n and 0 <= new_c < m:
if arr[new_r][new_c] == 0:
if visited[new_r][new_c][flag] == 0:
visited[new_r][new_c][flag] = visited[r][c][flag] + 1
q.append((new_r, new_c, flag))
else:
if flag == 0:
#print("(", new_r, ",", new_c, ") 에서 벽을 파괴")
visited[new_r][new_c][1] = visited[r][c][0] + 1
q.append((new_r, new_c, 1))
"""
for row in visited:
print(row)
print('='*20)
"""
# bfs 실행
bfs(0, 0, 0)
# 출력
if 0 in visited[n-1][m-1]:
min_dist = max(visited[n-1][m-1][0], visited[n-1][m-1][1])
else:
min_dist = min(visited[n-1][m-1][0], visited[n-1][m-1][1])
if min_dist == 0:
print(-1)
else:
print(min_dist)
🧂アイデア
BFS
🍳コード#コード#
from collections import deque
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
arr = [list(map(int, list(input().strip()))) for _ in range(n)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 3차원 배열로 표현
# visited[r][c][0] -> 벽을 한 번도 안 뚫었을 때
# visited[r][c][1] -> 벽을 한번이라도 뚫었을 때
visited = [[[0] * 2 for _ in range(m)] for __ in range(n)]
# flag가 1일 때 -> 벽을 한 번이라도 뚫음
# flag가 0일 때 -> 벽을 한 번도 안 뚫음
def bfs(r, c, flag):
q = deque([])
q.append((r, c, flag))
visited[r][c][flag] = 1
while q:
r, c, flag = q.popleft()
"""
if flag == 0:
print("벽을 파괴하지 않은", end=' ')
else:
print("벽을 파괴한", end=' ')
print("(", r, ",", c, ")", "에서 탐색한 결과")
"""
for i in range(4):
new_r = r + dx[i]
new_c = c + dy[i]
if 0 <= new_r < n and 0 <= new_c < m:
if arr[new_r][new_c] == 0:
if visited[new_r][new_c][flag] == 0:
visited[new_r][new_c][flag] = visited[r][c][flag] + 1
q.append((new_r, new_c, flag))
else:
if flag == 0:
#print("(", new_r, ",", new_c, ") 에서 벽을 파괴")
visited[new_r][new_c][1] = visited[r][c][0] + 1
q.append((new_r, new_c, 1))
"""
for row in visited:
print(row)
print('='*20)
"""
# bfs 실행
bfs(0, 0, 0)
# 출력
if 0 in visited[n-1][m-1]:
min_dist = max(visited[n-1][m-1][0], visited[n-1][m-1][1])
else:
min_dist = min(visited[n-1][m-1][0], visited[n-1][m-1][1])
if min_dist == 0:
print(-1)
else:
print(min_dist)
🧂アイデア
BFS
from collections import deque
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
arr = [list(map(int, list(input().strip()))) for _ in range(n)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 3차원 배열로 표현
# visited[r][c][0] -> 벽을 한 번도 안 뚫었을 때
# visited[r][c][1] -> 벽을 한번이라도 뚫었을 때
visited = [[[0] * 2 for _ in range(m)] for __ in range(n)]
# flag가 1일 때 -> 벽을 한 번이라도 뚫음
# flag가 0일 때 -> 벽을 한 번도 안 뚫음
def bfs(r, c, flag):
q = deque([])
q.append((r, c, flag))
visited[r][c][flag] = 1
while q:
r, c, flag = q.popleft()
"""
if flag == 0:
print("벽을 파괴하지 않은", end=' ')
else:
print("벽을 파괴한", end=' ')
print("(", r, ",", c, ")", "에서 탐색한 결과")
"""
for i in range(4):
new_r = r + dx[i]
new_c = c + dy[i]
if 0 <= new_r < n and 0 <= new_c < m:
if arr[new_r][new_c] == 0:
if visited[new_r][new_c][flag] == 0:
visited[new_r][new_c][flag] = visited[r][c][flag] + 1
q.append((new_r, new_c, flag))
else:
if flag == 0:
#print("(", new_r, ",", new_c, ") 에서 벽을 파괴")
visited[new_r][new_c][1] = visited[r][c][0] + 1
q.append((new_r, new_c, 1))
"""
for row in visited:
print(row)
print('='*20)
"""
# bfs 실행
bfs(0, 0, 0)
# 출력
if 0 in visited[n-1][m-1]:
min_dist = max(visited[n-1][m-1][0], visited[n-1][m-1][1])
else:
min_dist = min(visited[n-1][m-1][0], visited[n-1][m-1][1])
if min_dist == 0:
print(-1)
else:
print(min_dist)
BFS
1つ目のアイデアは、「壁がまだ破れていない場合、壁が破壊されたことを示し、その点でbfsを再実行する」(時間の複雑さを考慮してコードを記述する必要がある)
2 2
01
10
(r,c)毎にbfsが出力されると、🔽
벽을 파괴하지 않은 ( 0 , 0 ) 에서 탐색한 결과
( 1 , 0 ) 에서 벽을 파괴
( 0 , 1 ) 에서 벽을 파괴
[[1, 0], [0, 2]]
[[0, 2], [0, 0]]
====================
벽을 파괴한 ( 1 , 0 ) 에서 탐색한 결과
[[1, 3], [0, 2]]
[[0, 2], [0, 3]]
====================
벽을 파괴한 ( 0 , 1 ) 에서 탐색한 결과
[[1, 3], [0, 2]]
[[0, 2], [0, 3]]
====================
벽을 파괴한 ( 0 , 0 ) 에서 탐색한 결과
[[1, 3], [0, 2]]
[[0, 2], [0, 3]]
====================
벽을 파괴한 ( 1 , 1 ) 에서 탐색한 결과
[[1, 3], [0, 2]]
[[0, 2], [0, 3]]
====================
ヘルプ投稿:★☆☆★[必読]壁を破って移動するFAQ★☆★★★Reference
この問題について([伯俊2206]破壁後移動), 我々は、より多くの情報をここで見つけました https://velog.io/@eastgloss0330/백준-2206-벽-부수고-이동하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol