코딩테스트

[백준][구현] 주사위 굴리기 2

pythaac 2022. 4. 22. 21:06
BAEKJOON Online Judge(BOJ) 문제입니다.

https://www.acmicpc.net/

 

Baekjoon Online Judge

Baekjoon Online Judge 프로그래밍 문제를 풀고 온라인으로 채점받을 수 있는 곳입니다.

www.acmicpc.net

 

문제

https://www.acmicpc.net/problem/23288

 

23288번: 주사위 굴리기 2

크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼

www.acmicpc.net

 

내가 작성한 코드

import sys
from collections import deque, defaultdict

read = sys.stdin.readline
dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]
l, r, f, b, t, bt = 'l', 'r', 'f', 'b', 't', 'bt'

def read_data():
    N, M, K = map(int, read().rstrip().split())
    board = []
    for _ in range(N):
        board.append(list(map(int, read().rstrip().split())))

    return N, M, K, board

def in_range(x, y, N, M):
    return 0 <= x < N and 0 <= y < M

def reverse_dir(d):
    return (d + 2) % 4

def set_roll():
    roll = defaultdict(int)
    roll[t] = 1
    roll[b] = 2
    roll[r] = 3
    roll[l] = 4
    roll[f] = 5
    roll[bt] = 6
    return roll

def dice_rolling(roll, d):
    if d == 0:
        roll[r], roll[b], roll[bt], roll[t], roll[f], roll[l] = \
            roll[t], roll[b], roll[r], roll[l], roll[f], roll[bt]

    elif d == 1:
        roll[t], roll[b], roll[r], roll[l], roll[f], roll[bt] = \
            roll[b], roll[bt], roll[r], roll[l], roll[t], roll[f]
    elif d == 2:
        roll[t], roll[b], roll[r], roll[l], roll[f], roll[bt] = \
            roll[r], roll[b], roll[bt], roll[t], roll[f], roll[l]
    else:
        roll[t], roll[b], roll[r], roll[l], roll[f], roll[bt] = \
            roll[f], roll[t], roll[r], roll[l], roll[bt], roll[b]

def get_score(board, x, y, N, M):
    C = 0
    B = board[x][y]

    visited = defaultdict(bool)
    visited[(x, y)] = True
    q = deque([(x, y)])

    while q:
        r, c = q.popleft()

        C += 1

        for d_r, d_c in dir:
            nw_r, nw_c = r + d_r, c + d_c

            if in_range(nw_r, nw_c, N, M) and board[nw_r][nw_c] == B and not visited[(nw_r, nw_c)]:
                visited[(nw_r, nw_c)] = True
                q.append((nw_r, nw_c))

    return B * C


def rolling(x, y, d, N, M, roll, board):
    # 좌표
    nw_x, nw_y = x+dir[d][0], y+dir[d][1]
    if not in_range(nw_x, nw_y, N, M):
        d = reverse_dir(d)
        nw_x, nw_y = x+dir[d][0], y+dir[d][1]

    # 주사위
    dice_rolling(roll, d)

    # 점수
    score = get_score(board, nw_x, nw_y, N, M)

    # 방향
    if roll[bt] > board[nw_x][nw_y]:
        d = (d+1) % 4
    elif roll[bt] < board[nw_x][nw_y]:
        d = d-1 if d > 0 else 3

    return nw_x, nw_y, d, score


def get_answer(N, M, K, board):
    roll = set_roll()
    x, y, d, score = 0, 0, 0, 0

    for _ in range(K):
        nw_x, nw_y, nw_d, nw_score = rolling(x, y, d, N, M, roll, board)
        x, y, d = nw_x, nw_y, nw_d
        score += nw_score

    return score



N, M, K, board = read_data()
print(get_answer(N, M, K, board))
  • dictionary를 이용한 주사위 굴리기
    • 인덱스가 아닌 dictionary로 주사위가 굴러 바뀌는 값을 더 쉽게 구현

 

다른 사람이 작성한 코드

None
  • 강한 구현 문제로 다른 코드를 참고하지 않음

 

기억해야할 것