본문 바로가기

개발/algorithm

[백준 23288번] 주사위 굴리기2 - python

문제 링크

풀이 

백준 14499번 주사위 굴리기 를 풀었으면 그다지 어렵지 않게 풀 수 있는 문제이다.

 

주사위 굴리기 

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지

www.acmicpc.net

풀이

https://zzion2.tistory.com/345

 

[백준 14499번] 주사위 굴리기 - python

문제 링크 https://www.acmicpc.net/problem/14499 14499번: 주사위 굴리기 첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리..

zzion2.tistory.com

주사위 회전 방법에 대해서는 위 링크 참고

dx와 dy를 동쪽 -> 남쪽 -> 서쪽 -> 북쪽으로(시계방향으로) 저장하여 

- 반대 방향으로 가야한다면 (현재방향 + 2) % 4

- 시계 방향 90도 회전  (현재방향 + 1) % 4

- 반시계 방향 90도 회전 (현재방향 -1) % 4 

로 설정해주면 된다.

칸에 적힌 연결된 개수는 bfs 알고리즘으로 쉽게 구할 수 있다. 

from collections import deque 

n, m , k = map(int,input().split())

graph = []

# 위 뒤 오른쪽 왼쪽 앞 아래 -> 주사위 지도 모양대로
dice = [1, 2, 3, 4, 5, 6]
for _ in range(n):
    graph.append(list(map(int,input().split())))

# 오른쪽 아래 왼쪽 위 
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

# 현재 방향 동쪽 
direct = 0 

# 현재 주사위 위치 
x = 0 
y = 0
result = 0

def rotate(dir):
    a, b, c, d, e, f = dice[0],  dice[1], dice[2], dice[3], dice[4], dice[5]
    # 오른쪽으로 굴리기 
    if dir == 0 :
       dice[0], dice[1], dice[2], dice[3], dice[4], dice[5] = d, b, a, f, e, c
    # 아래로 굴리기 
    if dir == 1:
       dice[0],  dice[1], dice[2], dice[3], dice[4], dice[5] = b, f, c, d, a, e 
    # 왼쪽으로 굴리기 
    if dir == 2 :
        dice[0],  dice[1], dice[2], dice[3], dice[4], dice[5] = c, b, f, a, e, d
    # 위로 굴리기 
    if dir == 3:
        dice[0],  dice[1], dice[2], dice[3], dice[4], dice[5] = e, a, c, d, f, b
   
# 연결된 칸의 개수 구하기 
def bfs(x, y):
    q = deque()
    
    q.append((x,y))
    visited = [ [False] * m for _ in range(n)]
    num = graph[x][y]
    visited[x][y] = True 
    cnt = 1
    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 graph[nx][ny] == num:
                visited[nx][ny] = True 
                q.append((nx,ny))
                cnt += 1 
  
    return cnt 
    
for _ in range(k):
    
    # 현재 방향으로 이동 
    nx = x + dx[direct]
    ny = y + dy[direct]
    
    # 이동할 칸이 없다면 반대방향으로 
    if nx < 0 or nx >= n or ny < 0 or ny >= m :
        direct = (direct+2) % 4
        nx = x + dx[direct]
        ny = y + dy[direct]
    # 현재 위치 갱신 
    x = nx
    y = ny
    # 주사위 회전 
    rotate(direct)
    # 칸 점수 구하기 
    result += (graph[x][y] * bfs(x,y))

	# 주사위 바닥의 수가 더 크면 
    if dice[-1] > graph[x][y] :
    	# 시계 방향 회전 
        direct = (direct+1) % 4 
    # 주사위 바닥 수가 더 작으면 
    if dice[-1] < graph[x][y] :
    	# 반시계 방향 회전 
        direct = (direct-1) % 4 
    
print(result)