[ BOJ / Python ] 23288번 주사위 굴리기 2

황승환·2022년 7월 9일
0

Python

목록 보기
358/498


이번 문제는 삼성 기출 문제로, BFS와 시뮬레이션 문제이다. 문제에 대한 이해를 하는데에 시간이 꽤 걸렸던 것 같다. 문제를 해석해보면 주사위는 다음 주어진 조건대로 한칸씩 움직이고, 그 칸에 도착했을 때, 동서남북 4 방향을 확인해가며 현재 칸과 붙어있는 같은 값을 가진 칸들의 총 합을 점수로 얻는다는 것이었다.

우선 주사위의 눈금을 계속해서 갱신해야하기 때문에 패턴을 찾아보았고, 마주보는 면의 합이 7이 되는 것을 확인했다. 그래서 top, front, right만 저장하고, 이를 활용하였다. 즉, 변수로 정의하지 않은 bottom, back, left는 7-top, 7-front, 7-right가 되는 것이다.

현재 칸과 같은 값을 가지는 붙어있는 칸을 탐색하는 get_point함수는 BFS를 활용하여 쉽게 구현하였다. 탐색이 종료되면 누적된 포인트를 반환한다.

주사위를 움직이는 함수 move_dice는 주어진 방향대로 새로운 좌표를 만들고, 범위 확인을 하여 범위 내에 들어가지 않을 경우 방향을 반대로 바꾸고 다시 새로운 좌표를 만든 후, 각 방향으로의 이동에 따른 top, front, right를 갱신하도록 구현하였다.

주사위의 다음 방향을 판단하는 find_dir함수는 칸의 값과 bottom의 값을 비교하여 주어진 조건대로 방향을 갱신하도록 하였다.

Code

from collections import deque
n, m, k = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(n)]
top, front, right = 1, 5, 3 # 양면의 합은 7
dy, dx = [0, -1, 0, 1], [1, 0, -1, 0] # 동 북 서 남
def get_point(y, x):
    q = deque()
    q.append((y, x))
    visited = [[False for _ in range(m)] for _ in range(n)]
    visited[y][x] = True
    point = grid[y][x]
    while q:
        y, x = q.popleft()
        for i in range(4):
            ny, nx = y+dy[i], x+dx[i]
            if 0 <= ny < n and 0 <= nx < m and grid[ny][nx] == grid[y][x] and not visited[ny][nx]:
                visited[ny][nx] = True
                point += grid[ny][nx]
                q.append((ny, nx))
    return point
def move_dice(y, x, d):
    global top, front, right, cur, cur_d
    ny, nx = y+dy[d], x+dx[d]
    if not (0 <= ny < n and 0 <= nx < m):
        d = (d+2)%4
        cur_d = d
        ny, nx = y+dy[d], x+dx[d]
    if d == 0:
        top, front, right = 7-right, front, top
    elif d == 1:
        top, front, right = front, 7-top, right
    elif d == 2:
        top, front, right = right, front, 7-top
    elif d == 3:
        top, front, right = 7-front, top, right
    cur = [ny, nx]
def find_dir(i, y, x, d, bottom):
    if i == 0:
        return 0
    if bottom > grid[y][x]:
        return (d+3)%4
    elif bottom < grid[y][x]:
        return (d+1)%4
    else:
        return d
cur = [0, 0]
cur_d = 0
answer = 0
for i in range(k):
    cur_d = find_dir(i, cur[0], cur[1], cur_d, 7-top)
    move_dice(cur[0], cur[1], cur_d)
    answer += get_point(cur[0], cur[1])
print(answer)

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

0개의 댓글