읽기 전
- 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
- 개인적으로 배운 점을 정리한 글입니다.
문제 링크
문제 풀이
BFS 풀이 심화문제다. 3차원으로 배열이 확장되었을 뿐 풀이 자체는 그리 어렵진 않다. 다만 주의할 점으로는 별도로 토마토가 익어가는 시간만 체크할 수 있으면 기존 BFS, DFS 풀이처럼 방문했던 경로를 마킹하는 별도의 리스트를 생성할 필요가 없다는 점이다. 만약 별도의 리스트를 생성했다면 TLE(Time Limit Error)를 출력한다.
python 코드 - 1
from sys import stdin from collections import deque input = stdin.readline M, N, H = map(int, input().split()) # x, y, z, 좌표 입력 board = [[[0 for _ in range(M)] for _ in range(N)] for _ in range(H)] q = deque() # 큐 생성 for h in range(H): for r in range(N): cols = list(map(int, input().split())) for c, x in enumerate(cols): board[h][r][c] = x if x == 1: # 만약 익은 토마토라면 q.append([h, r, c, 0]) # 큐에 좌표값, 날짜 입력 dx = [1, -1, 0, 0, 0, 0] dy = [0, 0, -1, 1, 0, 0] dz = [0, 0, 0, 0, 1, -1] sol = 0 while q: # BFS 탐색 시작 z, y, x, c = q.popleft() for i in range(6): nx = x + dx[i] ny = y + dy[i] nz = z + dz[i] nc = c + 1 if 0 <= nx < M and 0 <= ny < N and 0 <= nz < H and board[nz][ny][nx] == 0: # 만약 좌표가 범위내고 해당 좌표의 상태가 익지 않은 토마토라면 board[nz][ny][nx] = 1 # 익었다고 마킹 q.append([nz, ny, nx, nc]) # 큐에 추가 sol = nc # 날짜 1 증가 zero = False for z in range(H): for y in range(N): if 0 in board[z][y]: sol = -1 zero = True break if zero: # 이중 for문 break break print(sol)
이 코드는 통과한 코드인데 여기서 조금 배운 점이 있었다. 위 코드와 로직이 정확히 동일한 코드였지만 단지 x, y, z 좌표를 이동할 때 하나의 리스트에 6가지 케이스([[0,0,1],[0,0,-1],...,[-1,0,0]]
형태의 리스트)를 담아서 매번 조회하는 코드를 제출한 결과 TLE가 발생하였다. python에서는 range로 정수범위 반복문을 호출하지 말고 완성된 list에서 원소 각각에 대해 접근을 권장하지만 시간 제한이 걸린 PS에서는 위 방법대로 정수 범위의 반복문을 선언한 뒤 좌표값으로 접근해야 할 것이다.
python 코드 - 2
from sys import stdin from collections import deque input = stdin.readline M, N, H = map(int, input().split()) board = [[[0 for _ in range(M)] for _ in range(N)] for _ in range(H)] q = deque() for h in range(H): for r in range(N): cols = list(map(int, input().split())) for c, x in enumerate(cols): board[h][r][c] = x if x == 1: q.append([h, r, c, 0]) dx = [1, -1, 0, 0, 0, 0] dy = [0, 0, -1, 1, 0, 0] dz = [0, 0, 0, 0, 1, -1] def bfs(sol): while q: z, y, x, c = q.popleft() for i in range(6): nx = x + dx[i] ny = y + dy[i] nz = z + dz[i] nc = c + 1 if 0 <= nx < M and 0 <= ny < N and 0 <= nz < H and board[nz][ny][nx] == 0: board[nz][ny][nx] = 1 q.append([nz, ny, nx, nc]) sol = nc return sol def check(sol): for z in range(H): for y in range(N): if 0 in board[z][y]: return -1 return sol sol = bfs(0) print(check(sol))
혹시나 해서 위 코드와 매우 똑같은 코드지만 함수로 감싸서 제출한 결과 속도가 거의 20%는 빨라졌다. PS의 경우 TLE가 걱정되는 탐색 문제라면 아예 함수로 제출하는 경우의 수도 고려해야겠다. 1번 코드는 5000ms였지만 2번 코드는 3800ms로 함수로 제출했을 뿐임에도 속도가 상당히 개선되었다.
'Algorithms > Baekjoon' 카테고리의 다른 글
BOJ #14500 테트로미노 (0) | 2021.06.19 |
---|---|
BOJ #14501 퇴사 (0) | 2021.06.19 |
BOJ #10799 쇠막대기 (0) | 2021.05.30 |
BOJ #6064 카잉 달력 (0) | 2021.05.07 |
BOJ #1629 곱셈 (0) | 2021.05.07 |