본문 바로가기
Algorithm/Baekjoon

2116. 주사위 쌓기 (Python, Swift)

by 원만사 2022. 4. 21.
반응형
 

2116번: 주사위 쌓기

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

www.acmicpc.net

 

풀이

 주사위를 접어보면 (A-F), (B-D), (C-E)와 같이 짝을 이루어 위와 아래가 된다. 즉, 입력으로 주어진 배열에서 인덱스로 봤을때 (0번-5번), (1번-3번), (2번-4번)과 같이 되는 것을 알 수 있다.

 

 1번 주사위에서 임의의 아랫면의 숫자를 정한다. 그렇게 되면 윗면의 숫자 역시 알 수 있다. 윗면과 아랫면의 숫자를 제외한 나머지 4개의 면 중에서 가장 큰 숫자를 찾아서 더해준다.

 1번의 위와 아래를 임시로 정하고 나면 나머지 주사위의 윗면과 아랫면은 순차적으로 정해진다. 1번 주사위의 윗면의 숫자를 2번 주사위의 아랫면 숫자로 설정하고 2번 주사위의 윗면 숫자를 구한다. 이번에도 2번 주사위의 윗면과 아랫면의 숫자를 제외한 나머지 4개의 면 중에서 가장 큰 숫자를 찾아서 더해준다.

 

 위와 같은 과정을 주사위의 개수만큼 반복해주면 답을 구할 수 있다.

 

코드

[Python]

import sys
input = sys.stdin.readline

# 처음 downNumber는 1번 주사위의 아랫면 숫자
def solve(downNumber):
    sum = 0

    for i in range(N):
        downIndex = dice[i].index(downNumber) # 1번 주사위의 아랫면 숫자의 인덱스 번호
        upIndex = upDown[downIndex] # 아랫면 숫자의 인덱스 번호를 통해 윗면 숫자의 인덱스 번호를 구할 수 있다.
        upNumber = dice[i][upIndex] # 윗면 숫자의 인덱스 번호를 이용해 윗면 숫자를 구한다.

        # i번째 주사위에서 윗면과 아랫면 숫자를 제외한 나머지 4개의 면 중에서 가장 큰 숫자를 sum에 더해준다.
        sum += max([x for x in dice[i] if x != downNumber and x != upNumber])

        downNumber = upNumber # 다음 주사위의 아랫면 숫자를 현재 주사위의 윗면 숫자로 설정한다.

    return sum


if __name__ == '__main__':
    N = int(input()) # 주사위의 개수
    dice = []
    upDown = [5, 3, 4, 1, 2, 0] # upDown[i]: 주사위의 i번 인덱스에 있는 값의 반대편 인덱스
    res = 0 

    for _ in range(N):
        dice.append(list(map(int, input().split())))

    # 1번 주사위의 아랫면 숫자를 i로 설정하여 함수 호출
    for i in range(1, 7):
        res = max(res, solve(i)) # res를 큰 값으로 업데이트

    print(res)

 

[Swift]

var N: Int = 0 // 주사위의 개수

if let input = readLine() {
    N = Int(input)!
}

var dice: [[Int]] = Array(repeating: Array(repeating: 0, count: 6), count: N)
let upDown: [Int] = [5, 3, 4, 1, 2, 0] // upDown[i]: 주사위의 i번 인덱스에 있는 값의 반대편 인덱스
var res: Int = 0

for i in 0..<N {
    if let input = readLine() {
        let inputs = input.split(separator: " ").map { Int($0)! }
        
        for j in 0..<6 {
            dice[i][j] = inputs[j]
        }
    }
}

// 처음 downNumber는 1번 주사위의 아랫면 숫자
func solve(_ downNumber: Int) -> Int {
    var sum: Int = 0
    var downNum: Int = downNumber
    
    for i in 0..<N {
        let downIndex: Int = dice[i].firstIndex(of: downNum)! // 1번 주사위의 아랫면 숫자의 인덱스 번호
        let upIndex: Int = upDown[downIndex] // 아랫면 숫자의 인덱스 번호를 통해 윗면 숫자의 인덱스 번호를 구할 수 있다.
        let upNum: Int = dice[i][upIndex] // 윗면 숫자의 인덱스 번호를 이용해 윗면 숫자를 구한다.
        
        // i번째 주사위에서 윗면과 아랫면 숫자를 제외한 나머지 4개의 면 중에서 가장 큰 숫자를 sum에 더해준다.
        var maxNum: Int = -1
        for j in 0..<6 {
            if dice[i][j] != downNum && dice[i][j] != upNum {
                maxNum = max(maxNum, dice[i][j])
            }
        }
        sum += maxNum
        
        downNum = upNum // 다음 주사위의 아랫면 숫자를 현재 주사위의 윗면 숫자로 설정한다.
    }
    
    return sum
}

// 1번 주사위의 아랫면 숫자를 i로 설정하여 메서드 호출
for i in 1...6 {
    res = max(res, solve(i)) // res를 큰 값으로 업데이트
}

print(res)
반응형

'Algorithm > Baekjoon' 카테고리의 다른 글

2539. 모자이크 (Python, Swift)  (1) 2022.04.23
2042. 구간 합 구하기 (Python)  (0) 2022.04.22
5014. 스타트링크 (Python, Swift)  (2) 2022.04.20
1016. 제곱 ㄴㄴ 수 (Python)  (0) 2022.04.19
1826. 연료 채우기 (Python)  (0) 2022.04.18

댓글