백준

23288 - 주사위 굴리기 2

whiporithm 2023. 8. 8. 23:59

 


 

문제

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

 

23288번: 주사위 굴리기 2

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

www.acmicpc.net

 

풀이

 

시뮬레이션 + 탐색 문제다.

 

탐색 같은 경우에는 bfs나 dfs방식으로 발판의 숫자로 체킹하면 된다.

 

조금 헷갈리는건 주사위를 굴리는 시뮬레이션인데, 나 같은 경우에는 우선 주사위를 임의로 배열로 선언했다. 

각 위치는 내가 임의로 선정했고, 그에 따라 동서남북 회전되었을때 배열을 갱신해주는 방식으로 풀이했다.

 

그 외에는 조건에 따라 시계방향, 반시계방향, 반대방향으로 방향을 바꿔주는 함수를 선언해서 조건에 맞춰 방향을 바꾸도록 설정했다.

 

코드

import sys
from sys import stdin
from collections import deque

def moveEast():
    global dice
    temp = dice[0]
    dice[0] = dice[4]
    dice[4] = dice[2]
    dice[2] = dice[5]
    dice[5] = temp

def moveWest():
    global dice
    temp = dice[0]
    dice[0] = dice[5]
    dice[5] = dice[2]
    dice[2] = dice[4]
    dice[4] = temp
    return dice

def moveNorth():
    global dice
    temp = dice[0]
    dice[0] = dice[1]
    dice[1] = dice[2]
    dice[2] = dice[3]
    dice[3] = temp

def moveSouth():
    global dice
    temp = dice[0]
    dice[0] = dice[3]
    dice[3] = dice[2]
    dice[2] = dice[1]
    dice[1] = temp

def getDirection(val, t):
    # 시계 방향
    if t == 0:
        if val == 3: return 0
        return val+1
    # 반시계 방향
    if t == 1:
        if val == 0: return 3
        return val-1
    # 반대 방향
    if t == 2:
        if val == 0: return 2
        if val == 1: return 3
        if val == 2: return 0
        if val == 3: return 1

def rotateDice(d):
    if d == 0 : moveEast()
    if d == 1 : moveSouth()
    if d == 2 : moveWest()
    if d == 3 : moveNorth()

def bfs(s, num):
    global n,m, board
    visited = [[False] * m for _ in range(n)]
    cnt = 1
    q = deque()
    visited[s[0]][s[1]] = True
    q.append(s)

    while q:
        x, y = q.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]

            if 0<=nx<n and 0 <=ny<m and not visited[nx][ny] and board[nx][ny] == num:
                visited[nx][ny] = True
                cnt+=1
                q.append((nx, ny))
    return cnt


dice = [1,5,6,2,4,3]
# 동 남 서 북
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

n, m, k = map(int, input().split())
board = [list(map(int, stdin.readline().rstrip().split())) for _ in range(n)]
x = y = 0
direction = 0
answer = 0
for _ in range(k):
    nx = x + dx[direction]
    ny = y + dy[direction]

    # 범위 밖이라면 => 반대 방향으로 틀어준다.
    if nx < 0 or nx >= n or ny < 0 or ny >= m:
        direction = getDirection(direction, 2)
        nx = x + dx[direction]
        ny = y + dy[direction]

    x = nx
    y = ny
    rotateDice(direction)
    # 점수 획득
    answer += (board[nx][ny] * bfs((nx, ny), board[nx][ny]))
    if dice[2] > board[nx][ny]:
        direction = getDirection(direction, 0)
    elif dice[2] < board[nx][ny]:
        direction = getDirection(direction, 1)

print(answer)

 

후기

 

주사위 굴리기 1도 풀었던 거 같은데 거의 똑같았던 거 같은 기억..

'백준' 카테고리의 다른 글

23290 - 마법사 상어와 복제  (0) 2023.08.11
21611 - 마법사 상어와 블리자드  (0) 2023.08.10
19238 - 스타트 택시  (0) 2023.08.08
21610 - 마법사 상어와 비바라기  (0) 2023.07.07
21609 - 상어 중학교  (0) 2023.07.07