[파이썬] 백준 16441 : 아기돼지와 늑대 (골드3)
16441번: 아기돼지와 늑대
첫 번째 줄에는 격자의 행의 수를 나타내는 N (3 ≤ N ≤ 100) 과 격자의 열의 수를 나타내는 M (3 ≤ M ≤ 100) 이 주어집니다. 두 번째 줄부터 N개의 줄에 지도의 정보를 나타내는 길이가 M인 문자열
www.acmicpc.net
문제
풀이
0. 방향성 생각
- 빙판이 들어가는 방향마다 이동경로가 다르게 처리된다. 같은 빙판에 접근하더라도 들어가는 방향에 따라 다를 수 있기 때문에, 좌표에 대해서 방문처리하면 다른 방향으로 못갈 수도 있다.
- visit 좌표 위치에 4방향을 넣어서 방문체크를 한다.
1. 입력
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = [list(input()) for _ in range(h)]
visit = [[[False]*4 for _ in range(w)] for _ in range(h)]
dire = [(1,0),(0,1),(-1,0),(0,-1)]
q = deque()
for i in range(h):
for j in range(w):
if arr[i][j] == 'W':
visit[i][j] = [True]*4
q.append((j,i))
- 늑대가 시작점은 모두 방문처리 해주고 큐에 추가.
2. 함수 정의
while q:
x,y = q.popleft()
for d in range(4):
dx,dy = dire[d]
nx,ny = x+dx,y+dy
nxt = arr[ny][nx]
if not visit[ny][nx][d]:
if nxt == '.' or nxt == 'W':
visit[ny][nx][d] = True
q.append((nx,ny))
elif nxt == '+':
for i in range(100):
nnx,nny = nx+i*dx,ny+i*dy
nnxt = arr[nny][nnx]
if not visit[nny][nnx][d]:
if nnxt == '.' or nnxt == 'W':
visit[nny][nnx][d] = True
q.append((nnx,nny))
break
elif nnxt == '#':
q.append((nnx-dx,nny-dy))
break
else:
visit[nny][nnx][d] = True
else:
break
- 다음 위치가 초원이면 해당 초원으로 들어가는 방향으로 방문처리 해주고 해당 좌표를 큐에 추가.
- 빙판을 밟은 경우 앞으로 계속 전진하는 코드를 for문으로 구현했다.
- 해당 빙판 방향으로 접근한 적이 없는 경우, 그 방향으로 visit을 계속 True를 해준다.
- 산을 만난 경우 nnx-dx,nny-dy로 산 이전의 좌표를 큐에 넣어준다. 더 전진하지 못하므로 break
- 초원을 만난 경우 바로 멈출 수 있으니, 방문처리하고 큐에 넣고 탈출
- 만약 해당 방향 빙판으로 접근했으면 for문 돌릴 필요 없으니 바로 탈출
3. 출력
for i in range(h):
s = ''
for j in range(w):
if arr[i][j] == '.':
s += '.' if any(visit[i][j]) else 'P'
else:
s += arr[i][j]
print(s)
- visit의 해당 좌표에서 하나라도 True 체크가 되어있으면 안전하지 않으므로 .
- 모두 False이면 P
- 그렇지 않은 경우 그대로 복사해주기.
전체코드
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = [list(input()) for _ in range(h)]
visit = [[[False]*4 for _ in range(w)] for _ in range(h)]
dire = [(1,0),(0,1),(-1,0),(0,-1)]
q = deque()
for i in range(h):
for j in range(w):
if arr[i][j] == 'W':
visit[i][j] = [True]*4
q.append((j,i))
while q:
x,y = q.popleft()
for d in range(4):
dx,dy = dire[d]
nx,ny = x+dx,y+dy
nxt = arr[ny][nx]
if not visit[ny][nx][d]:
if nxt == '.' or nxt == 'W':
visit[ny][nx][d] = True
q.append((nx,ny))
elif nxt == '+':
for i in range(100):
nnx,nny = nx+i*dx,ny+i*dy
nnxt = arr[nny][nnx]
if not visit[nny][nnx][d]:
if nnxt == '.' or nnxt == 'W':
visit[nny][nnx][d] = True
q.append((nnx,nny))
break
elif nnxt == '#':
q.append((nnx-dx,nny-dy))
break
else:
visit[nny][nnx][d] = True
else:
break
for i in range(h):
s = ''
for j in range(w):
if arr[i][j] == '.':
s += '.' if any(visit[i][j]) else 'P'
else:
s += arr[i][j]
print(s)
코멘트
다 풀어놓고 복붙하다가 로직 변경하는거 조금씩 빼먹는데 주석 달아서 체크하면서 넘어가기
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 백준 5719 : 거의 최단 경로 (플레5) (0) | 2023.12.19 |
---|---|
[파이썬] 백준 2021 : 최소 환승 경로 (골드2) (0) | 2023.12.17 |
[파이썬] 백준 5213 : 과외맨 (골드2) (0) | 2023.12.17 |
[파이썬] 백준 2887 : 행성터널 (플레5) (0) | 2023.12.16 |
[파이썬] 백준 16933 : 벽 부수고 이동하기 3 (골드1) (0) | 2023.12.16 |
[파이썬] 백준 14442 : 벽 부수고 이동하기 2 (골드3) (0) | 2023.12.15 |
[파이썬] 백준 1414 : 불우이웃돕기 (골드3) (0) | 2023.12.13 |
댓글