ABOUT ME

woongS, iOS, succesS 삼쓰의 개발 블로그

Today
Yesterday
Total
  • 백준 1041 주사위
    Algorithm/BOJ 2020. 6. 30. 15:37
    728x90

    출처: www.acmicpc.net/problem/1041

    분류: Greedy


    접근방식

    주사위를 쌓아서 정육면체를 만들 때 각 주사위에서 서로 마주보는 면이 동시에 보일 수는 없습니다. 
    따라서 마주보는 면이 안 나오게 잘 계산해서 최소값을 구해줘야 합니다.
    주어진 도면에서 각 주사위의 마주보는 면은 (0, 5), (1, 4), (2, 3) 입니다.
    (주사위 1개인 경우 제외)

    만들어진 정육면체에서 각 주사위는 3가지 케이스 밖에 생기지 않고 각 케이스의 개수는 아래와 같습니다.

    세 면이 보이는 경우 4개 ( 각 모서리 위쪽 )

    두 면이 보이는 경우 4(N-1) + 4(N-2)  (옆면 모서리 + 위쪽 모서리)
    한 면이 보이는 경우 4N(N-2) + (N-2)(N-2) (테두리를 제외한 옆면 + 테두리를 제외한 윗면)
    마주보는 경우만 아니라면 주사위를 잘 굴려서 3가지 케이스를 만들어줄 수 있습니다.

     

    각 케이스에 될 수 있는 경우의 수 중에서 최소를 찾아주면 됩니다.

    세 면이 보이는 경우: 대칭이 되는 세 쌍 중에서 각각의 최소들의 합
    두 면이 보이는 경우: 마주보는 면이 아닌 두 면의 합 중 최소
    한 면이 보이는 경우: 주사위 6면 중 최소

     

    해결방법

    let n = Int(readLine()!)!
    let dice = readLine()!.split(separator: " ").map{Int($0)!}
    let oneFaceMin = dice.min()!
    var twoFaceMin = Int.max
    var threeFaceMin = Int.max
    
    for (face, value) in dice.enumerated() {
      for secondIndex in 0...5 {
        if secondIndex == face || secondIndex == (5-face) {
          continue
        }
        for thirdIndex in 0...5 {
          if thirdIndex == face ||
            thirdIndex == 5-face ||
            secondIndex == thirdIndex ||
            secondIndex == 5-thirdIndex {
            continue
          }
          //print("threeFace: (\(face),\(secondIndex), \(thirdIndex))")
          threeFaceMin = min(value + dice[secondIndex] + dice[thirdIndex], threeFaceMin)
        }
        //print("twoFace: (\(face),\(secondIndex)")
        twoFaceMin = min(value + dice[secondIndex], twoFaceMin)
      }
    }
    
    
    
    if n == 1 {
      let diceSum = dice.reduce(0, +)
      print(diceSum - dice.max()!)
    } else {
      print(threeFaceMin*4 + twoFaceMin*(n-1)*4 + twoFaceMin*(n-2)*4 + oneFaceMin*(n-1)*(n-2)*4 + oneFaceMin*(n-2)*(n-2))
    }

    저는 조금 복잡하게 풀었었는데 다른 분의 풀이는 보니 이렇게 간단하게 풀 수 도 있더라구요

    let n = Int(readLine()!)!
    let dice = readLine()!.split(separator: " ").map{Int($0)!}
    let oneFaceMin = dice.min()!
    
    var faceMin = [Int]()
    faceMin.append(min(dice[0], dice[5]))
    faceMin.append(min(dice[1], dice[4]))
    faceMin.append(min(dice[2], dice[3]))
    faceMin.sort()
    let threeFaceMin = faceMin[0] + faceMin[1] + faceMin[2]
    let twoFaceMin = faceMin[0] + faceMin[1]
    
    if n == 1 {
      let diceSum = dice.reduce(0, +)
      print(diceSum - dice.max()!)
    } else {
      print(threeFaceMin*4 + twoFaceMin*(n-1)*4 + twoFaceMin*(n-2)*4 + oneFaceMin*(n-1)*(n-2)*4 + oneFaceMin*(n-2)*(n-2))
    }
    
    

     

    배운점

     

    3중 포문으로 굉장히 복잡하게 풀었었는데

    다른 분들의 풀이를 보다가 모서리가 마주보는 면 중 최소들의 합이라는 사실에 무릎을 탁 쳤습니다.

    화이팅

     

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

    백준 15686 치킨 배달  (0) 2020.07.13
    BOJ 14889 스타트와 링크  (0) 2020.07.08
    BOJ 1439 뒤집기  (0) 2020.06.22
    백준 2812 크게 만들기  (0) 2020.06.22
    백준 3019 빵집  (0) 2020.06.18
Designed by Tistory.