백준 - 주사위 굴리기 2 / Gold 3 / 23288번 / Python

Ed Park·2023년 3월 23일
0
post-custom-banner

문제 📋

백준 - 주사위 굴리기2


풀이 📝

import sys


class Dice:
    def __init__(self, up, down, left, right, top, bottom):
        self.up = up
        self.down = down
        self.left = left
        self.right = right
        self.top = top
        self.bottom = bottom

    def move(self, way):
        if way == 0:
            self.move_right()
        elif way == 1:
            self.move_down()
        elif way == 2:
            self.move_left()
        else:
            self.move_up()

    def move_up(self):
        temp_top = self.top
        self.top = self.down
        self.down = self.bottom
        self.bottom = self.up
        self.up = temp_top

    def move_down(self):
        temp_top = self.top
        self.top = self.up
        self.up = self.bottom
        self.bottom = self.down
        self.down = temp_top

    def move_left(self):
        temp_top = self.top
        self.top = self.right
        self.right = self.bottom
        self.bottom = self.left
        self.left = temp_top

    def move_right(self):
        temp_top = self.top
        self.top = self.left
        self.left = self.bottom
        self.bottom = self.right
        self.right = temp_top


def decide_direction(direction: int, bottom: int, target: int):
    if bottom > target:
        direction = (direction + 1) % 4
    elif bottom < target:
        direction -= 1
        if direction < 0:
            direction += 4
    return direction


def calc_score(target: int, pos: tuple):
    cnt = 0
    visited = [[False] * m for _ in range(n)]
    delta = [(1, 0), (0, 1), (-1, 0), (0, -1)]
    stack = [pos]
    visited[pos[0]][pos[1]] = True

    while stack:
        row, col = stack.pop()
        cnt += 1

        for i in range(4):
            delta_row, delta_col = delta[i]

            new_row = row + delta_row
            new_col = col + delta_col

            if new_row < 0 or new_row >= n or new_col < 0 or new_col >= m:
                continue

            if not visited[new_row][new_col] and grid[new_row][new_col] == target:
                visited[new_row][new_col] = True
                stack.append((new_row, new_col))

    return cnt * target


def solution(n: int, m: int, k: int, grid: list):
    answer = 0
    direction = 0
    row, col = 0, 0
    dice = Dice(2, 5, 4, 3, 1, 6)
    delta = [(0, 1), (1, 0), (0, -1), (-1, 0)]

    while k > 0:
        delta_row, delta_col = delta[direction]
        new_row = row + delta_row
        new_col = col + delta_col

        if new_row < 0 or new_row >= n or new_col < 0 or new_col >= m:  # 맵을 벗어나면 반대 방향으로 전환.
            direction = (direction + 2) % 4
            continue

        row = new_row
        col = new_col

        dice.move(direction)  # 주사위 이동.

        answer += calc_score(grid[row][col], (row, col))  # 점수 계산.

        direction = decide_direction(direction, dice.bottom, grid[row][col])  # 다음 방향 결정.
        k -= 1

    return answer


n, m, k = map(int, sys.stdin.readline().split())
grid = [list(map(int, sys.stdin.readline().split())) for _ in range(n)]

print(solution(n, m, k, grid))


조금 복잡한 구현 문제이다.
복잡할수록 함수를 나눠서 차례대로 개발하면서 디버깅해야 한다.
따라서 다음과 같은 순서로 개발을 진행했다.

1. 주사위 동작 구현 -> 주사위 클래스, move 함수 구현.
2. 이동과 방향 전환 구현 -> decide_direction() 함수 구현.
3. 점수 계산 구현 (DFS 탐색) -> calc_score() 함수 구현.

profile
Simple is the best
post-custom-banner

0개의 댓글