ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BOJ 23288, Python 3] 주사위 굴리기 2
    알고리즘/BOJ 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
    반응형

    댓글

Designed by Tistory.