백준

2116 - 주사위 쌓기 (Java)

whiporithm 2024. 9. 23. 22:34

 


 

문제

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

 

풀이

 

 

첫번째 주사위는 6면 모두 아랫면으로 향할 수 있기 때문에, 초기 값 기준으로 6번의 반복문을 돌아 경우의 수를 판단한다.

 

그 외의 주사위는 한칸씩 쌓으면서 아랫면이, 아래 주사위의 윗면과 맞닿으면 된다.

 

이 때, 새롭게 쌓는 주사위의 아랫면과 윗면을 제외한 4면 중 가장 큰 값을 취하고,

 

이 과정을 반복하면 된다. 

 

주사위 쌓는 과정을 상세하게 설명하면,

 

1. 주사위를 쌓을때 아래 주사위의 윗면 값을 현재 주사위의 인덱스 어디에 있는지 찾는다. 

  (만약 아랫면 주사위의 윗면이 5라고 했을때, 현재 주사위에 5가 어느 위치에 있는지 찾으면 된다.)

주사위는 정수형 배열로 인덱스로 위치를 파악할 수 있다.

 

2. 해당 인덱스와, 윗면 인덱스를 제외한 4면에서 가장 큰 값을 찾는다.

※ 문제 사진 기준으로 A (인덱스로는 0) 가 아랫면 인덱스라면 윗면 인덱스는 F (인덱스 값은 5) 가 될 것이고, 이 두면을 제외한 4면 중 가장 큰 값을 고르면 된다.

 

3. 윗면 인덱스의 값을 1번의 "아래 주사위의 윗면 값" 으로 갱신한다음 반복하면 된다.

 

코드

import java.util.*;
import java.io.*;

public class Main {
    public static int[] oppositeValue = {5, 3, 4, 1, 2, 0};
    public void solution() throws Exception {
        int answer = 0;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        List<List<Integer>> dices = new ArrayList<>();

        int n = Integer.parseInt(br.readLine());
        for (int i = 0; i < n; i++) {
            String[] s = br.readLine().split(" ");
            List<Integer> temp = new ArrayList<>();
            for(int j=0; j<s.length; j++){
                temp.add(Integer.parseInt(s[j]));
            }
            dices.add(temp);
        }

        // 가장 아래 주사위는 원하는 대로 둘 수 있다.
        for (int i = 0; i < 6; i++) {

            int tempAnswer = getMaxSide(i, dices.get(0)); // 첫번째 주사위

            int floorIndex = i; // 초기 바닥면

            int ceilingIndex = oppositeValue[i]; // 초기 윗면
            int ceilingValue = dices.get(0).get(ceilingIndex);


            for (int j = 1; j < dices.size(); j++) { // 첫번째 주사위부터 끝 주사위까지

                floorIndex = getFloorIndex(ceilingValue, dices.get(j)); // 윗면을 바닥면으로 설정한다.

                ceilingIndex = oppositeValue[floorIndex]; // 윗면을 구한다.
                ceilingValue = dices.get(j).get(ceilingIndex);


                tempAnswer += getMaxSide(floorIndex, dices.get(j)); // floorIndex 값을 밑으로 두었을 때 가장 큰 옆면을 구한다.
            }

            answer = Math.max(answer, tempAnswer);
        }

        System.out.println(answer);
    }

    public int getMaxSide(int floorNumber, List<Integer> dice) {
        if (floorNumber == 0 || floorNumber == 5) {
            return Collections.max(Arrays.asList(dice.get(1), dice.get(2), dice.get(3), dice.get(4)));
        }
        if (floorNumber == 1 || floorNumber == 3) {
            return Collections.max(Arrays.asList(dice.get(0), dice.get(2), dice.get(4), dice.get(5)));
        }
        if (floorNumber == 2 || floorNumber == 4) {
            return Collections.max(Arrays.asList(dice.get(0), dice.get(1), dice.get(3), dice.get(5)));
        }
        return -1;
    }

    public int getFloorIndex(int value, List<Integer> dice) {
        for (int i = 0; i < dice.size(); i++) {
            if(value == dice.get(i)) return i;
        }
        return -1;
    }

    public static void main(String[] args) throws Exception {
        new Main().solution();
    }
}

 

후기

'백준' 카테고리의 다른 글

20955 - 민서의 응급 수술 (Java)  (0) 2024.10.01
1079 - 쇠 막대기 (Java)  (0) 2024.09.26
15662 - 톱니바퀴(2)  (0) 2024.09.23
1043 - 거짓말 (Java)  (0) 2024.09.21
1374 - 강의실 (Java)  (1) 2024.09.19