백준 - 2116번(주사위 쌓기)

최지홍·2022년 2월 23일
0

백준

목록 보기
77/145

문제 출처: https://www.acmicpc.net/problem/2116


문제

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

  • 주사위 쌓기 놀이는 아래에서부터 1번 주사위, 2번 주사위, 3번 주사위, … 의 순서로 쌓는 것이다. 쌓을 때 다음과 같은 규칙을 지켜야 한다: 서로 붙어 있는 두 개의 주사위에서 아래에 있는 주사위의 윗면에 적혀있는 숫자는 위에 있는 주사위의 아랫면에 적혀있는 숫자와 같아야 한다. 다시 말해서, 1번 주사위 윗면의 숫자는 2번 주사위 아랫면의 숫자와 같고, 2번 주사위 윗면의 숫자는 3번 주사위 아랫면의 숫자와 같아야 한다. 단, 1번 주사위는 마음대로 놓을 수 있다.

  • 이렇게 쌓아 놓으면 긴 사각 기둥이 된다. 이 사각 기둥에는 4개의 긴 옆면이 있다. 이 4개의 옆면 중에서 어느 한 면의 숫자의 합이 최대가 되도록 주사위를 쌓고자 한다. 이렇게 하기 위하여 각 주사위를 위 아래를 고정한 채 옆으로 90도, 180도, 또는 270도 돌릴 수 있다. 한 옆면의 숫자의 합의 최댓값을 구하는 프로그램을 작성하시오.


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(reader.readLine()); // 주사위 개수
		
		List<List<Integer>> dice = new ArrayList<>();
		
		for (int i = 0; i < N; i++) {
			StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
			dice.add(new ArrayList<>(6));
			for (int j = 0; j < 6; j++) {
				dice.get(i).add(Integer.parseInt(tokenizer.nextToken()));
			}
		}
		
		// 서로 마주보고 있는 숫자 인덱스 목록
		HashMap<Integer, Integer> pair = new HashMap<>();
		pair.put(0, 5);
		pair.put(5, 0);
		pair.put(1, 3);
		pair.put(3, 1);
		pair.put(2, 4);
		pair.put(4, 2);
		
		int answer = 0;
		
		// 각 경우의 수 처리
		for (Map.Entry<Integer, Integer> entry : pair.entrySet()) {
			// 초깃값 세팅
			int bottom = entry.getKey();	// 밑 인덱스
			int top = entry.getValue();		// 위 인덱스
			
			int topValue = dice.get(0).get(top); // 위의 값 -> 이게 추후 밑 값으로 가야됨
			
			int result = 0;
			
			for (List<Integer> list : dice) {
				bottom = list.indexOf(topValue); 	// 새로운 밑 찾기
				top = pair.get(bottom);				// 위의 값에 해당하는 인덱스
				
				int tempMax = 0;
				
				for (int i = 0; i < list.size(); i++) {
					if (i == bottom || i == top) continue; 
					tempMax = Math.max(tempMax, list.get(i));
				}
				
				result += tempMax;
				
				topValue = list.get(top);
			}
			
			answer = Math.max(answer, result);
		}
		
		System.out.println(answer);
	}

}

  • 각각의 주사위들의 숫자 정보를 담는 리스트를 담는 리스트를 선언한다.
  • 서로 마주보고 있는 인덱스의 목록을 HashMap으로 생성한다.
  • 6가지 경우의 수가 있는데 이 모든 경우를 고려하기 위해 반복문을 수행한다.
  • 반복문을 돌면서 제일 밑 주사위의 값들을 변경시키며 진행한다.
  • 처음 초기값으로 뽑은 값을 주사위의 윗면에 오는 값으로 가정하고 해당 인덱스에 해당하는 값을 구한다.
  • 반복을 돌면 그 값이 새로운 주사위의 바닥쪽 숫자가 된다. 리스트에서 그 숫자의 인덱스를 찾고 위의 인덱스도 갱신해준다.
  • 두 인덱스를 찾았으면, 그 두 값을 제외한 나머지 값들 중에서 최댓값을 찾는다.
  • 최댓값들을 더해주고 아까 찾은 위의 인덱스를 통해 주사위 윗면의 값을 찾아 변수를 업데이트한다.
profile
백엔드 개발자가 되자!

0개의 댓글