알고리즘/BOJ

[BOJ 23288, Python 3] 주사위 굴리기 2

70825 2021. 10. 25. 19:48
반응형

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

 

23288번: 주사위 굴리기 2

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

www.acmicpc.net

 

이번에 나온 삼성 SW 역량테스트 문제입니다.

 

 

 

풀이

먼저 점수를 저장할 배열을 만들어주고, 플러드 필을 이용하여 본문에 나온대로 각 칸마다 B와 C를 곱한 값을 점수 배열에 저장하면 됩니다. 이 부분은 쉬우니까 넘어가겠습니다.

 

문제는 주사위를 굴리는 것입니다. 이것은 전개도 그림을 사용하여 설명하겠습니다.

처음 전개도가 위와 같이 있을 때, 설명하기 쉬운 남쪽과 북쪽으로 이동하는 것부터 설명하겠습니다.

먼저 남쪽으로 움직이는 경우에는 윗 면이 1이었던게 2가 되기 때문에 전개도의 가운데 줄이 컨베이어 벨트처럼 위에서 아래로 움직이게 됩니다.

북쪽으로 움직이는 경우에는 윗 면이 1이었던게 5가 되기 때문에 남쪽과는 반대로 전개도의 가운데 줄이 아래에서 위로 움직이게 됩니다.

 

동쪽으로 움직일 때는 숫자 4가 윗 면이 되므로 두번째 줄의 숫자가 오른쪽으로 이동하고, 숫자 3과 숫자 6의 자리를 바꾸게 됩니다. 이 과정은 결과적으로 아래 사진과 같습니다.

서쪽으로 움직일 때는 숫자 3이 윗 면이 되므로 동쪽으로 움직일 때와 반대로 두번째 줄의 숫자가 왼쪽으로 이동하고, 숫자 4와 숫자 6의 자리를 바꾸게 됩니다. 이 과정도 결과적으로 아래 사진과 같습니다.

 

이처럼 주사위를 굴리는 방향에 따라 해당 숫자의 동서남북 숫자가 달라지게 되니 전개도 배열을 하나 만들어서 움직일 때마다 전개도를 수정해주시면 됩니다.

 

 

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from collections import deque
input = __import__('sys').stdin.readline
dx, dy =[010-1], [10-10]
 
n, m, z = map(int, input().split())
arr = [[*map(int, input().split())] for _ in range(n)]
 
# 플러드 필
score = [[0* m for _ in range(n)]
visit = [[0* m for _ in range(n)]
for i in range(n):
    for j in range(m):
        if not visit[i][j]:
            q = deque([[i, j]])
            visit[i][j] = 1; val = 1
            coordinate = [(i, j)]
            while q:
                x, y = q.popleft()
                for k in range(4):
                    nx, ny = x + dx[k], y + dy[k]
                    if 0 <= nx < n and 0 <= ny < m and not visit[nx][ny] and arr[x][y] == arr[nx][ny]:
                        visit[nx][ny] = 1; val += 1
                        coordinate.append((nx, ny))
                        q.append([nx, ny])
            for x, y in coordinate:
                score[x][y] = arr[x][y] * val
 
# 주사위 굴리기
dice = [215643# 전개도
down = [0654321]
ans = 0
arrow = 0 # (0 으론쪽 이동, 1 아래 이동, 2 왼쪽 이동, 3 위 이동) : 전개도는 반대로 움직임
x, y = 00
nx, ny = 00
for _ in range(z):
    x, y = nx, ny
    nx, ny = x + dx[arrow], y + dy[arrow]
    if not(0 <= nx < n and 0 <= ny < m): # 이동할 수 없으면 반대 방향으로 이동
        arrow = (arrow + 2) % 4
        nx, ny = x + dx[arrow], y + dy[arrow]
 
    ans += score[nx][ny]
 
    if arrow == 0: dice[4], dice[1], dice[5], dice[3= dice[3],dice[4], dice[1], dice[5]
    if arrow == 1: dice[0], dice[1], dice[2], dice[3= dice[3], dice[0], dice[1], dice[2]
    if arrow == 2: dice[4], dice[1], dice[5], dice[3= dice[1], dice[5], dice[3], dice[4]
    if arrow == 3: dice[0], dice[1], dice[2], dice[3= dice[1], dice[2], dice[3], dice[0]
 
    if dice[3> arr[nx][ny] : arrow = (arrow + 1) % 4
    if dice[3< arr[nx][ny] : arrow = (arrow + 3) % 4
 
print(ans)
cs
반응형