나의 기록, 현진록

[Swift] 백준 2116 주사위 쌓기 본문

Programming/Algorithm & Data Structure

[Swift] 백준 2116 주사위 쌓기

guswlsdk 2024. 12. 3. 15:47
반응형

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

 

1. 문제이해

  • 마주 보는 면에 적힌 숫자의 합이 반드시 7이 되는 것이 아닌 주사위
  • 주사위를 아래에서부터 위로 쌓기
  • 주사위 쌓기 규칙은 다음과 같다
    • 서로 붙어 있는 주사위가 아래에 있는 주사위의 윗면 숫자와 위에 있는 주사위의 아랫면 숫자가 일치해야 한다.
    • 1번 주사위는 마음대로 놓을 수 있다.
    • 주사위의 윗면과 아랫면은 고정하고 회전 시킬 수 있다.
  • 주사위 쌓기 규칙을 준수하며 최종적으로 긴 사각 기둥이 되도록 주사위를 쌓았을 때 총 네 개의 옆면 중 어느 한면의 숫자의 합의 최댓값을 구하기

 

2. 접근방법

  • 숫자 배열 → 전개도 → 주사위 추상화
  • 마주 보는 면의 쌍 구하기
    • [A, F] → [0, 5]
    • [B, D] → [1, 3]
    • [C, E] → [2, 4]
  • 주사위 윗면/아랫면만 정하면 윗면/아랫면을 제외한 주사위의 최댓값을 구하기
    • 주사위 회전 가능

 

3. 설계

  1. 첫번째 주사위의 윗면을 1부터 6까지(주사위가 가질 수 있는 수) 반복
    1. 1부터 6까지의 반복할 때마다 옆면의 최댓값을 저장할 변수 선언
  2. 아랫 주사위의 윗면 == 현재 주사위의 아랫면
    • 현재 주사위의 윗면이 현재 주사위 다음으로 쌓을 주사위의 아랫면과 같아야 하니 기준 값 갱신
    • 현재 주사위의 윗면 아랫면을 제외한 옆면의 최댓값 변수에 누적
  3. 1~6까지 2번 과정을 반복할 때마다 옆면의 최댓값 중 가장 큰 값 출력

 

func solution(){
    let N = Int(readLine()!)!
    var diceList = [[Int]]()
    var result = 0
    for _ in 0..<N{
        diceList.append(readLine()!.split(separator: " ").map{Int(String($0))!})
    }
    
    func pairIndex(value: Int) -> Int{
        if value == 0{
            return 5
        }else if value == 1{
            return 3
        }else if value == 2{
            return 4
        }else if value == 4{
            return 2
        }else if value == 3{
            return 1
        }else{
            return 0
        }
    }
    
    for first in 1...6{
        var sum = 0
        var top = first // 다음 주사위의 아랫면
        for diceIndex in 0..<N{
            for (offset, bottom) in diceList[diceIndex].enumerated(){
                if top == bottom{ // 아래 주사위의 윗면 == 윗 주사위의 아랫면
                    let newTop = diceList[diceIndex][pairIndex(value: offset)]
                    top = newTop // 아래 주사위의 윗면 갱신

                    // 윗면과 아랫면을 제외한 나머지 수 중 최대값 구하기
                    var tempDiceList = diceList[diceIndex]
                    tempDiceList.remove(at: tempDiceList.firstIndex(of: bottom)!)
                    tempDiceList.remove(at: tempDiceList.firstIndex(of: newTop)!)
                    sum += tempDiceList.max()!
                    break
                }
            }
        }
        result = max(result, sum)
    }
    print(result)
}
반응형