본문 바로가기
Algorithm/BAEKJOON

[백준/Python] 2116번 - 주사위 쌓기

by code_pie 2024. 1. 3.

 

 

천수는 여러 종류의 주사위를 가지고 쌓기 놀이를 하고 있다. 주사위의 모양은 모두 크기가 같은 정육면체이며 각 면에는 1부터 6까지의 숫자가 하나씩 적혀있다. 그러나 보통 주사위처럼 마주 보는 면에 적혀진 숫자의 합이 반드시 7이 되는 것은 아니다.

 

주사위 쌓기 놀이는 아래에서부터 1번 주사위, 2번 주사위, 3번 주사위, … 의 순서로 쌓는 것이다.

 

쌓을 때 다음과 같은 규칙을 지켜야 한다: 서로 붙어 있는 두 개의 주사위에서 아래에 있는 주사위의 윗면에 적혀있는 숫자는 위에 있는 주사위의 아랫면에 적혀있는 숫자와 같아야 한다.

 

다시 말해서, 1번 주사위 윗면의 숫자는 2번 주사위 아랫면의 숫자와 같고, 2번 주사위 윗면의 숫자는 3번 주사위 아랫면의 숫자와 같아야 한다. 단, 1번 주사위는 마음대로 놓을 수 있다.

 

이렇게 쌓아 놓으면 긴 사각 기둥이 된다. 이 사각 기둥에는 4개의 긴 옆면이 있다. 이 4개의 옆면 중에서 어느 한 면의 숫자의 합이 최대가 되도록 주사위를 쌓고자 한다.

 

이렇게 하기 위하여 각 주사위를 위 아래를 고정한 채 옆으로 90도, 180도, 또는 270도 돌릴 수 있다. 한 옆면의 숫자의 합의 최댓값을 구하는 프로그램을 작성하시오.

 
 
 

입력

 

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다.

 

주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는 주사위의 전개도에서 A, B, C, D, E, F 의 순서로 입력된다. 입력되는 숫자 사이에는 빈 칸이 하나씩 있다. 주사위의 개수는 10,000개 이하이며 종류가 같은 주사위도 있을 수 있다.

 

 

 

출력

 

첫줄에 한 옆면의 숫자의 합이 가장 큰 값을 출력한다.

 

 

풀이

 

주사위의 ABCDEF의 위치가 정해져 있으므로 밑면이 A일때 윗면은 F, B일때 D를 dictionary로 변환해 줬다. (A=0, B=1 ... F=5로 변환)

그리고 첫 주사위의 윗면에는 1~6의 수가 올 수 있는데, 첫 주사위의 윗면이 정해지면 나머지 주사위들의 윗면과 밑면은 자동으로 정해진다. 그러므로 각 주사위의 윗면과 밑면을 뺀 나머지 숫자들 중 최댓값을 구하면 한 옆면의 숫자의 합의 최댓값이 나온다. (주사위는 밑면과 아래 주사위의 윗면의 숫자만 같으면 옆면은 회전이 가능하기 때문)

[풀이 요약]

  1. 맨 아래층 주사위의 윗면에 어떤 숫자가 올지를 정하고(6가지 경우의 수), 옆면에 올 수 있는 가장 큰 수를 구한다.
  2. 그 다음층 주사위의 아랫면을 같은 숫자로 정하면 윗면의 숫자를 알 수 있다.
  3. 현재 주사위의 윗면과 아랫면을 뺀 수들 중 가장 큰 숫자를 더한다.
  4. 맨 윗층의 주사위까지 2, 3 번 과정을 반복한다.
  5. 6가지 경우의 수 중에서 옆면의 수가 가장 큰 수를 출력한다.

 

 

Code

 

 

from sys import stdin
input = stdin.readline
def side_sum(dice_high,up,s):
    sum=s
    while True:
        num=6
        for i in range(6):
            if lst[dice_high+1][i]==lst[dice_high][up]: #위층 주사위의 밑면이 아래층 주사위의 윗면과 같으면
                if lst[dice_high+1][i]==6 or lst[dice_high+1][dic[i]]==6:
                    num=5
                    if lst[dice_high+1][i]==5 or lst[dice_high+1][dic[i]]==5:
                        num=4
                up=dic[i] # 윗면갱신
                break 
        dice_high+=1
        sum+=num
        if dice_high==N-1:
            ans.append(sum)
            return 
        
dic={0:5, 1:3, 2:4, 3:1, 4:2, 5:0}
N=int(input())
lst=[list(map(int,input().split())) for _ in range(N)]
ans=[]
for i in range(6):
    num_1=6
    if lst[0][i]==6 or lst[0][dic[i]]==6:
        num_1=5
        if lst[0][i]==5 or lst[0][dic[i]]==5:
            num_1=4
    up=dic[i]
    side_sum(0,up,num_1)
print(max(ans))

 


 
특별히 생각해야 하거나 힘든게 없는 문제였던 것 같다

 

 

2116번: 주사위 쌓기

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는

www.acmicpc.net

 

반응형