313. 불 (another version)
1) 어떤 전략(알고리즘)으로 해결?
- 하나의 큐에서 가장 먼저 불의 위치를 저장하고 마지막의 상근이의 위치를 저장하는 식으로 한 queue에서 이를 해결한다.
- 우선 불을 움직이고, 사람을 움직이는 순서로 진행한다.
2) 코딩 설명
<내 풀이>
from collections import deque
import sys
dirr = [-1,1,0,0]
dirc = [0,0,-1,1]
test_case = int(sys.stdin.readline().rstrip())
for t in range(test_case) :
w,h = map(int,sys.stdin.readline().rstrip().split())
graph = []
q = deque()
for i in range(h) :
graph.append(list(str(sys.stdin.readline().rstrip())))
for j in range(w) :
if graph[i][j] == '*' :
q.append((i,j))
graph[i][j] = "F"
elif graph[i][j] == '@' :
graph[i][j] = 1
start = (i,j)
q.append((start))
while q :
chkr, chkc = q.popleft()
fire_or_time = graph[chkr][chkc]
if str(fire_or_time) != "F" and (chkc == 0 or chkc == w-1 or chkr == 0 or chkr == h-1):
print(graph[chkr][chkc])
break
for num in range(4) :
tmpr, tmpc = chkr+dirr[num], chkc+dirc[num]
if 0<=tmpr<h and 0<=tmpc<w :
if graph[tmpr][tmpc]=='.' :
if fire_or_time == "F" :
graph[tmpr][tmpc] = "F"
else :
graph[tmpr][tmpc] = fire_or_time+1
q.append((tmpr,tmpc))
else : print("IMPOSSIBLE")
< 내 틀렸던 풀이, 문제점>
from collections import deque
import sys
dirr = [-1,1,0,0]
dirc = [0,0,-1,1]
test_case = int(sys.stdin.readline().rstrip())
for t in range(test_case) :
w,h = map(int,sys.stdin.readline().rstrip().split())
graph = []
for i in range(h) :
graph.append(list(str(sys.stdin.readline().rstrip())))
fireq = deque()
sgq = deque()
for r in range(h) :
for c in range(w) :
if graph[r][c] == '*' :
fireq.append((r,c))
graph[r][c] = 1
elif graph[r][c] == '@' :
graph[r][c] = 0
sgq.append((r,c,1))
while fireq :
chkr, chkc = fireq.popleft()
now_time = graph[chkr][chkc]
for num in range(4) :
tmpr, tmpc = chkr+dirr[num], chkc+dirc[num]
if 0<=tmpr<h and 0<=tmpc<w :
if graph[tmpr][tmpc]=='.' or graph[tmpr][tmpc]=='@' :
graph[tmpr][tmpc] = now_time+1
fireq.append((tmpr,tmpc))
answer = int(1e9)
while sgq :
nowr, nowc, sg_time = sgq.popleft()
graph[nowr][nowc]=0
if nowr == 0 or nowr == h-1 or nowc == 0 or nowc == w-1 :
print(sg_time)
break
for num in range(4) :
tmpr, tmpc = nowr+dirr[num], nowc+dirc[num]
if 0<=tmpr<h and 0<=tmpc<w :
if graph[tmpr][tmpc] == '.' :
sgq.append((tmpr, tmpc, sg_time+1))
elif graph[tmpr][tmpc]!='#' :
if str(graph[tmpr][tmpc]).isdigit() and 0<int(graph[tmpr][tmpc]) and int(graph[tmpr][tmpc]) > sg_time:
sgq.append((tmpr, tmpc, sg_time+1))
else : print("IMPOSSIBLE")
- 반례
불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다.
라는 문제 조건을 제대로 읽지 않았었다
1
3 3
*.*
.@.
*.*
output: 2
answer: IMPOSSIBLE
from collections import deque
import sys
dirr = [-1,1,0,0]
dirc = [0,0,-1,1]
test_case = int(sys.stdin.readline().rstrip())
for t in range(test_case) :
w,h = map(int,sys.stdin.readline().rstrip().split())
graph = []
for i in range(h) :
graph.append(list(str(sys.stdin.readline().rstrip())))
fireq = deque()
sgq = deque()
for r in range(h) :
for c in range(w) :
if graph[r][c] == '*' :
fireq.append((r,c))
graph[r][c] = 1
elif graph[r][c] == '@' :
graph[r][c] = 0
sgq.append((r,c,1))
while fireq :
chkr, chkc = fireq.popleft()
now_time = graph[chkr][chkc]
for num in range(4) :
tmpr, tmpc = chkr+dirr[num], chkc+dirc[num]
if 0<=tmpr<h and 0<=tmpc<w :
if graph[tmpr][tmpc]=='.' or graph[tmpr][tmpc]=='@' :
if not str(graph[tmpr][tmpc]).isdigit():
graph[tmpr][tmpc] = now_time+1
fireq.append((tmpr,tmpc))
answer = int(1e9)
while sgq :
nowr, nowc, sg_time = sgq.popleft()
graph[nowr][nowc]=0
if nowr == 0 or nowr == h-1 or nowc == 0 or nowc == w-1 :
print(sg_time)
break
for num in range(4) :
tmpr, tmpc = nowr+dirr[num], nowc+dirc[num]
if 0<=tmpr<h and 0<=tmpc<w :
if graph[tmpr][tmpc] == '.' :
sgq.append((tmpr, tmpc, sg_time+1))
elif graph[tmpr][tmpc]!='#' :
if str(graph[tmpr][tmpc]).isdigit() and 0<int(graph[tmpr][tmpc]) and int(graph[tmpr][tmpc]) > sg_time+1:
sgq.append((tmpr, tmpc, sg_time+1))
else : print("IMPOSSIBLE")
<반성 점>
- 문제 조건을 제대로 안 읽었던 점이 문제였다.
불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다.
라는 구절을 잘 봤어야 했다.
<배운 점>
- 기존에는 불을 먼저 옮기고, 그 이후에 상근이를 옮기는 방식으로 했습니다.
- 이렇게 되면 불필요한 초 까지 고려해서