[알고리즘][파이썬] 백준 2116번 - 주사위 쌓기

한상진·2021년 4월 15일
0

알고리즘

목록 보기
3/6


처음 떠올렸던 접근 방법

  1. 주사위의 윗면과 아랫면에 어떤 수를 두는게 가장 최대값을 손해보지 않는지 찾는다.
  2. 최대값을 손해보지 않게 주사위를 쌓는다(4개의 옆면을 모두 확인).
  3. 쌓여진 주사위의 4개의 옆면의 각각의 합을 구한다.
  4. 4개의 옆면의 각각의 합 중 가장 큰 수를 출력한다.

처음부터 접근 방법을 완전히 잘못 떠올렸다.
떠올린 접근 방법대로 코드를 짜보려고 하니 멘붕이었다.
결국 다른 사람들의 접근 방법을 참고했다.

개선된 접근 방법

  1. 주사위의 아랫면에 따라 윗면이 어떻게 결정되는지 로테이션을 dictionary에 저장한다.
  2. 첫 번째 주사위를 기준으로, 아랫면을 두는 모든 경우의 수(1~6)을 확인한다.
  3. 모든 경우의 수를 순회하며 각각의 경우의 최대값과 이전의 최대값을 비교한다.
  4. 최종적인 최대값을 출력한다.

최종 입력 코드

N = int(input())
dice = []
for _ in range(N):
    dice.append(list(map(int, input().split())))
rotate = {0 : 5, 1 : 3, 2 : 4, 3 : 1, 4 : 2, 5 : 0} # 주사위의 아랫면에 따른 윗면 로테이션 등록(리스트 인덱스 기준)

maxnum = 0 # 최대값을 저장해둘 상수 선언
for i in range(6): # 첫 번째 주사위를 기준으로 1~6까지 모두 순회
    result = [] #각 주사위마다 옆면의 최대값 1개를 저장해둘 리스트 선언
    temp = [1, 2, 3, 4, 5, 6] # 주사위 각 면에 써져있는 1~6
    temp.remove(dice[0][i]) # 주사위 아랫면의 숫자 제거
    next = dice[0][rotate[i]] # 첫 번째 주사위의 윗면 값 계산
    temp.remove(next) # 첫 번째 주사위의 윗면 값 삭제
    result.append(max(temp)) # 첫 번째 주사위의 옆면들 중 가장 큰 값 삽입
    for j in range(1, N): # 두 번째 주사위부터 마지막 주사위까지 반복
        temp = [1, 2, 3, 4, 5, 6]
        temp.remove(next) # 현재 주사위의 아랫면 숫자 제거
        next = dice[j][rotate[dice[j].index(next)]] # 현재 주사위의 윗면 계산
        temp.remove(next) # 현재 주사위의 윗면 삭제
        result.append(max(temp)) # 현재 주사위의 옆면들 중 가장 큰 값 삽입
    result = sum(result) # 각 주사위마다의 최대값을 모두 더한다.
    if maxnum < result: # 이전의 최대값과 현재의 최대값을 비교하여 더 큰 값을 저장한다.
        maxnum = result

print(maxnum)

이 문제는 접근 방법을 떠올리기가 너무 어려웠는데 정답비율이 60%에다가 2003년 정보올림피아드 초등부 문제라고 하여 내 자신이 너무 자괴감이 들었다.
열심히 공부해야겠다................ㅠㅠ

profile
공부방

0개의 댓글