[ BOJ / Python ] 2931번 가스관

황승환·2022년 8월 12일
0

Python

목록 보기
436/498

이번 문제는 구현 시뮬레이션 문제로, 다음 좌표를 찾고 해당 좌표에서의 탐색을 진행하기 위해 BFS를 활용하였다. 딕셔너리를 활용하여 각 블록에 들어왔을 때의 방향과 그에 해당하는 다음 방향을 매핑시켰고, 주어진 파이프대로 따라가다가 .을 만났을 때 주변 4 방향을 확인하여 조건에 맞는 방향을 임시 리스트에 담았고, 임시 리스트의 길이와 내용에 따라 맞는 파이프를 넣어주고 함수를 종료시키도록 하였다. 조건들이 생각보다 복잡하여 시간이 조금 오래 걸렸다. 그래도 한번에 해결되어서 기분이 좋았다.

Code

from collections import deque
r, c = map(int, input().split())
grid = [list(str(input())) for _ in range(r)]
dy, dx = [0, 1, 0, -1], [1, 0, -1, 0]
mapping = {'1': {2: 1, 3: 0}, '2': {1: 0, 2: 3}, '3': {0: 3, 1: 2}, '4': {0: 1, 3: 2}}
dot = {0: 2, 1: 3, 2: 0, 3: 1}
sy, sx = 0, 0
for i in range(r):
    for j in range(c):
        if grid[i][j] == 'M':
            sy, sx = i, j
def chk(ny, nx, cur_d):
    if cur_d == 0 and grid[ny][nx] in ('3', '4'):
        return True
    if cur_d == 1 and grid[ny][nx] in ('2', '3'):
        return True
    if cur_d == 2 and grid[ny][nx] in ('1', '2'):
        return True
    if cur_d == 3 and grid[ny][nx] in ('1', '4'):
        return True
    return False
def m_to_z():
    q = deque()
    q.append((sy, sx, -1))
    visited = [[False for _ in range(c)] for _ in range(r)]
    visited[sy][sx] = True
    while q:
        y, x, d = q.popleft()
        if grid[y][x] == 'M':
            for i in range(4):
                ny, nx = y+dy[i], x+dx[i]
                if 0 <= ny < r and 0 <= nx < c and grid[ny][nx] != '.':
                    visited[ny][nx] = True
                    q.append((ny, nx, i))
        elif grid[y][x] == '|' or grid[y][x] == '-':
            ny, nx = y+dy[d], x+dx[d]
            if 0 <= ny < r and 0 <= nx < c and not visited[ny][nx]:
                visited[ny][nx] = True
                q.append((ny, nx, d))
        elif grid[y][x] == '+':
            for i in range(4):
                ny, nx = y+dy[i], x+dx[i]
                if 0 <= ny < r and 0 <= nx < c and not visited[ny][nx]:
                    visited[ny][nx] = True
                    q.append((ny, nx, i))
        elif grid[y][x] in ('1', '2', '3', '4'):
            nxt_d = mapping[grid[y][x]][d]
            ny, nx = y+dy[nxt_d], x+dx[nxt_d]
            if 0 <= ny < r and 0 <= nx < c and not visited[ny][nx]:
                visited[ny][nx] = True
                q.append((ny, nx, nxt_d))
        elif grid[y][x] == '.':
            tmp = []
            for i in range(4):
                if i == dot[d]:
                    continue
                ny, nx = y+dy[i], x+dx[i]
                if 0 <= ny < r and 0 <= nx < c:
                    if grid[ny][nx] != '.':
                        if grid[ny][nx] == '+' or (i in (1, 3) and grid[ny][nx] == '|') or (i in (0, 2) and grid[ny][nx] == '-') or chk(ny, nx, i):
                            tmp.append(i)
            if len(tmp) == 1:
                if d == tmp[0]:
                    if tmp[0] == 1 or tmp[0] == 3:
                        result = [y+1, x+1, '|']
                        return result
                    if tmp[0] == 0 or tmp[0] == 2:
                        result = [y+1, x+1, '-']
                        return result
                else:
                    for key, value in mapping.items():
                        for before, nxt in mapping[key].items():
                            if d == before and tmp[0] == nxt:
                                result = [y+1, x+1, key]
                                return result
            elif len(tmp) == 3:
                result = [y+1, x+1, '+']
                return result
print(*m_to_z())

profile
꾸준함을 꿈꾸는 SW 전공 학부생의 개발 일기

0개의 댓글