물
과 고슴도치
의 이동 로직을 따로 둔건 한눈에 알아보기 쉽게 하려고 한거였는데 다 짜고 나니 중복도 많고 비효율적으로 짠 것 같다.물이 채워질 공간
먼저 조사하고나서 고슴도치 이동시킨다.(물이 채워질 예정인 칸은 고슴도치가 이동할 수 없기 때문이다.)다음에 채워질 칸
을 미리 *
(물) 표시를 하려고 했는데 그랬더니다음에 채워질 칸
에 있던(아직 물이 안온 곳) 고슴도치가 죽어서다음에 채워질 칸
들은 덱
에 넣어놓고 고슴도치가 이동하려는 방향
이물이 찰 예정인 칸
과 같다면 이동못하게 했다.계속 시간초과
에 메모리 초과
떠서 한시간을 디버깅했지만 해결하지 못했다. -> 탈출 못함
x, y = water_list.popleft()
tiddup_forest[x][y] = '*'
visited
를 만들고 nx
, ny
를 조사할 때 방문이 된 것들은 방문하지 않는다.if 0 <= nx < r and 0 <= ny < c and tiddup_forest[nx][ny] != 'D' and tiddup_forest[nx][ny] != 'X' and not visited[nx][ny]:
water_list.append((nx, ny))
visited[nx][ny] = 1
O(r * c)
from collections import deque
import sys
input = sys.stdin.readline
# 물은 매 분마다 비어있는 칸으로 확장한다. (X, D)는 이동 불가능.
def water(water_list, w_cnt):
# 물의 개수만큼만 물이 찰 예정인 칸 조사한다.
while w_cnt > 0:
w_cnt -= 1
x, y = water_list.popleft()
tiddup_forest[x][y] = '*'
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
if 0 <= nx < r and 0 <= ny < c and tiddup_forest[nx][ny] != 'D' and tiddup_forest[nx][ny] != 'X' and not visited[nx][ny]:
water_list.append((nx, ny))
visited[nx][ny] = 1
return water_list
# 고슴도치는 인접한 네칸 중 하나로 이동할 수 있다. (*, X)는 이동 불가능.
# + 물이 찰 예정인 칸으로 이동할 수 없다.
def gosumdochi(move_list, move_cnt):
global result
while move_cnt > 0:
move_cnt -= 1
x, y, time = move_list.popleft()
# 이미 물이 찬 지역이면 없던걸로 한다
if tiddup_forest[x][y] == '*':
continue
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
if 0 <= nx < r and 0 <= ny < c:
if tiddup_forest[nx][ny] == 'D':
print(time + 1)
exit(0)
elif tiddup_forest[nx][ny] != 'X' and tiddup_forest[nx][ny] != '*' and tiddup_forest[nx][ny] != 'S' and tiddup_forest[nx][ny] not in water_list:
move_list.append((nx, ny, time + 1))
tiddup_forest[nx][ny] = 'S'
visited[nx][ny] = 1
r, c = map(int, input().split())
tiddup_forest = [list(input().strip()) for _ in range(r)]
move_list = deque([])
water_list = deque([])
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
visited = [[0] * c for _ in range(r)]
# 고슴도치 위치와 물의 위치 찾기
for i in range(r):
for j in range(c):
if tiddup_forest[i][j] == 'S':
move_list.append((i, j, 0))
elif tiddup_forest[i][j] =='*':
water_list.append((i, j))
while move_list:
# 이동하기 전에 물이 찰 공간 체크
w_cnt = len(water_list)
if water_list:
water(water_list, w_cnt)
# 고슴도치 이동
move_cnt = len(move_list)
gosumdochi(move_list, move_cnt)
print("KAKTUS")
고슴도치와 물을 같은 덱
에 담는다.
-> 고슴도치가 물이 찰 예정인 칸에 못가는 것은 물에 잠기기 때문이다
-> 그냥 물에 잠기게 하면 그쪽으로 이동 안하면 되니까
-> 고슴도치를 먼저 덱
에 넣어서 이동시킨 후, 물을 이동시킨다.
각 거리는 visited
를 이용해서 체크해준다.
appendleft
를 알게 되었다(왼쪽 끝에 원소를 입력한다.)from collections import deque
import sys
input = sys.stdin.readline
# 이동
def move(q):
while q:
x, y = q.popleft()
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
if 0 <= nx < r and 0 <= ny < c:
# 고슴도치일 때(물, 돌, 방문했던 곳 X)
if tiddup_forest[x][y] == 'S':
if tiddup_forest[nx][ny] == 'D':
return visited[x][y] + 1
elif tiddup_forest[nx][ny] != 'X' and tiddup_forest[nx][ny] != '*' and not visited[nx][ny]:
visited[nx][ny] = visited[x][y] + 1 # 방문처리 + 거리
tiddup_forest[nx][ny] = 'S'
q.append((nx, ny))
# 물일 때(비버굴, 돌, 방문했던 곳 X)
else:
if tiddup_forest[nx][ny] != 'D' and tiddup_forest[nx][ny] != 'X' and tiddup_forest[nx][ny] != '*':
tiddup_forest[nx][ny] = '*' # 방문처리
q.append((nx, ny))
return "KAKTUS"
r, c = map(int, input().split())
tiddup_forest = [list(input().strip()) for _ in range(r)]
q = deque([])
visited = [[0] * c for _ in range(r)] # 각 위치별 거리
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
for i in range(r):
for j in range(c):
if tiddup_forest[i][j] == 'S':
q.appendleft((i, j))
elif tiddup_forest[i][j] =='*':
q.append((i, j))
print(move(q))