[백준 1041] 주사위 - JAVA

WTS·2025년 12월 19일

코딩 테스트

목록 보기
14/81

문제

    +---+        
    | D |        
+---+---+---+---+
| E | A | B | F |
+---+---+---+---+
    | C |        
    +---+        

주사위는 위와 같이 생겼다.
주사위의 여섯 면에는 수가 쓰여 있다.
위의 전개도를 수가 밖으로 나오게 접는다.

A,B,C,D,E,FA, B, C, D, E, F에 쓰여 있는 수가 주어진다.

지민이는 현재 동일한 주사위를 N3N^3개 가지고 있다.
이 주사위를 적절히 회전시키고 쌓아서, N×N×NN×N×N크기의 정육면체를 만들려고 한다.
이 정육면체는 탁자위에 있으므로, 55개의 면만 보인다.

NN과 주사위에 쓰여 있는 수가 주어질 때,
보이는 55개의 면에 쓰여 있는 수의 합의 최솟값을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 NN이 주어진다. 둘째 줄에 주사위에 쓰여 있는 수가 주어진다.
위의 그림에서 A, B, C, D, E, FA,\ B,\ C,\ D,\ E,\ F에 쓰여 있는 수가 차례대로 주어진다.
NN1,000,0001,000,000보다 작거나 같은 자연수이고, 쓰여 있는 수는 5050보다 작거나 같은 자연수이다.

출력

첫째 줄에 문제의 정답을 출력한다.


접근 방법

이 문제는 머릿속으로 N×N×NN×N×N을 시뮬레이션만 잘하면 어렵지 않게 풀 수 있습니다.

N이 1인 경우

가장 큰 한 면을 제외하고 나머지 면들의 숫자를 계산하면 정답을 구할 수 있습니다.

N이 2인 경우

88개의 정육면체로 구성되며
위쪽의 4개의 정육면체는 3개의 면을
아래쪽 4개의 정육면체는 2개의 면이 보이므로
정육면체에서 가장 작은 3개의 면과 2개의 면을 구하면 됩니다.

이 때 주의할 점은 면과 면이 마주보는 경우는 없으니 반드시 제외해야 합니다.
그러므로 최솟값을 구한다고 정육면체의 전개도 순서를 정렬해서는 안됩니다.
반복문으로도 간단히 마주보는 면에 대한 로직을 처리할 수 있습니다.

N이 3 이상인 경우

NN이 2인 경우에서 큰 정육면체의 꼭짓점에 대한 최솟값들은 해결했습니다.
나머지 길어지면서 발생하는 모서리 부분
큰 정육면체의 테두리를 제외한 안쪽의 면들에 대해 최솟값들을 구해햐합니다.

꼭짓점을 제외하고 나머지 범위는 NN의 크기에 따라 동적으로 변경되기 때문에
range=N2range = N-2 로 정의합니다.

두 면이 보이는 모서리는 총 8개, 그리고 모서리의 길이는 rangerange
이를 계산한다면 two×range×8two \times range \times 8
한 면이 보이는 모서리는 4개, 이를 계산하면 one×range×4one \times range \times 4
테두리를 제외한 안쪽 면은 총 5개, 이를 계산하면 one×range×range×5one \times range \times range \times 5

위와 같은 로직을 통해 문제를 해결할 수 있었습니다.


코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static StringTokenizer st;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());

        int one = 50;
        int[] cube = new int[6];
        for (int i = 0; i < 6; i++) {
            cube[i] = Integer.parseInt(st.nextToken());
            one = Math.min(one, cube[i]);
        }

        int five = getMinFiveSurface(cube);
        int three = getMinThreeSurface(cube);
        int two = getMinTwoSurface(cube);


        long answer = 0;
        if (N == 1) answer += five;
        else {
            answer += three * 4 + two * 4;
            if (N > 2) {
                long range = N - 2;
                answer += two * range * 8;
                answer += one * range * range * 5;
                answer += one * range * 4;
            }
        }

        System.out.println(answer);
    }

    static int getMinFiveSurface(int[] cube) {
        int max = 0;
        int sum = 0;
        for (int i = 0; i < 6; i++) {
            max = Math.max(max, cube[i]);
            sum += cube[i];
        }

        return sum - max;
    }

    static int getMinThreeSurface(int[] cube) {
        int min = 150;
        for (int i = 0; i < 4; i++) {
            for (int j = i + 1; j < 5; j++) {
                if (j == 5 - i) continue;
                for (int k = j + 1; k < 6; k++) {
                    if (k == 5 - i || k == 5 - j) continue;
                    min = Math.min(min, cube[i] + cube[j] + cube[k]);
                }
            }
        }

        return min;
    }

    static int getMinTwoSurface(int[] cube) {
        int min = 100;
        for (int i = 0; i < 5; i++) {
            for (int j = i + 1; j < 6; j++) {
                if (j == 5 - i) continue;
                min = Math.min(min, cube[i] + cube[j]);
            }
        }

        return min;
    }
}
profile
while True: study()

0개의 댓글