practivceAlgorithm/백준

[백준][Python][삼성 2021 하반기 코딩테스트] 23288 주사위 굴리기2

findTheValue 2021. 10. 26. 01:30

주사위 굴리기 1이랑 비슷합니다.

주사위 좌표이동, 방향에 따른 회전,

위치에 따른 좌표 값 * cnt 만큼 최종합에 더해줌.

주사위 밑면과 지도값 비교에 따라 방향성 수정

 

위의 4가지 로직으로 이루어져 있습니다.

사실 새로운 지도 배열을 만든 후 거기에 미리 위치마다 더해야 하는 값을 미리 연산해 두면 같은 위치마다 bfs를 돌지 않아도 되지만 통과됐으니 생략.. 아래가 직관적인 로직이라고 생각합니다.

 

import sys
input = sys.stdin.readline
from collections import deque


def rotate_dice(d):
    if d == 0:
        dice['top'], dice['left'], dice['bottom'], dice['right'] = dice['left'], dice['bottom'], dice['right'], dice['top']
    elif d == 1:
        dice['top'], dice['up'], dice['bottom'], dice['down'] = dice['up'], dice['bottom'], dice['down'], dice['top']
    elif d == 2:
        dice['left'], dice['bottom'], dice['right'], dice['top'] = dice['top'], dice['left'], dice['bottom'], dice['right']
    else:
        dice['up'], dice['bottom'], dice['down'], dice['top'] = dice['top'], dice['up'], dice['bottom'], dice['down']


def bfs(x, y, pivot):
    q = deque()
    q.append((x, y))
    cnt = 1
    visited = set()
    visited.add((x, y))
    while q:
        x, y = q.popleft()
        for dx, dy in delta:
            nx, ny = x + dx, y + dy
            if 0 <= nx < N and 0 <= ny < M and maps[nx][ny] == pivot and (nx, ny) not in visited:
                visited.add((nx, ny))
                cnt += 1
                q.append((nx, ny))
    return cnt * pivot


def move(x, y, k):
    global answer
    q = []
    q.append((x, y, 0))
    while k:
        x, y, direction = q.pop()
        nx, ny = x + delta[direction][0], y + delta[direction][1]
        if nx < 0 or nx >= N:
            direction = (direction + 2) % 4
            nx, ny = x + delta[direction][0], y + delta[direction][1]
        elif ny < 0 or ny >= M:
            direction = (direction + 2) % 4
            nx, ny = x + delta[direction][0], y + delta[direction][1]
        # 방향성에 따라 주사위 회전
        rotate_dice(direction)
        # bfs answer갱신
        answer += bfs(nx, ny, maps[nx][ny])
        # bottom값과 map값 사이 비교 후 방향 수정
        if dice['bottom'] > maps[nx][ny]:
            direction = (direction + 1) % 4
        elif dice['bottom'] < maps[nx][ny]:
            direction = (direction - 1) % 4
        q.append((nx, ny, direction))
        k -= 1


N, M, K = map(int, input().split())
maps = [list(map(int, input().split())) for _ in range(N)]
dice = {'up': 2, 'left': 4, 'top': 1, 'right': 3, 'down': 5, 'bottom': 6}
delta = ((0, 1), (1, 0), (0, -1), (-1, 0))
answer = 0

# 이동
move(0, 0, K)
print(answer)