문제
백준 1041번
https://www.acmicpc.net/problem/1041
주사위는 위와 같이 생겼다. 주사위의 여섯 면에는 수가 쓰여 있다. 위의 전개도를 수가 밖으로 나오게 접는다.
A, B, C, D, E, F에 쓰여 있는 수가 주어진다.
지민이는 현재 동일한 주사위를 N^3개 가지고 있다. 이 주사위를 적절히 회전시키고 쌓아서, N×N×N크기의 정육면체를 만들려고 한다. 이 정육면체는 탁자위에 있으므로, 5개의 면만 보인다.
N과 주사위에 쓰여 있는 수가 주어질 때, 보이는 5개의 면에 쓰여 있는 수의 합의 최솟값을 출력하는 프로그램을 작성하시오.
첫째 줄에 N이 주어진다. 둘째 줄에 주사위에 쓰여 있는 수가 주어진다. 위의 그림에서 A, B, C, D, E, F에 쓰여 있는 수가 차례대로 주어진다. N은 1,000,000보다 작거나 같은 자연수이고, 쓰여 있는 수는 50보다 작거나 같은 자연수이다.
- 생각해보기
- 주사위의 면이 보이는 정도를 나눠서 계산한다.
- 한 면이 보이는 주사위, 두 면이 보이는 주사위, 세 면이 보이는 주사위
- 면 별로 갯수의 규칙을 찾아 식으로 나타낸다.
예시(N이 3일 경우)
- 총 27개의 주사위
- 한 면이 보이는 주사위(갯수 : (N - 2) * (5 * N - 6))
- 두 면이 보이는 주사위(갯수 : 8 * N - 12)
- 세 면이 보이는 주사위(갯수 : 4)
Code
- N이 1일 경우와 아닐 경우를 나누어 생각한다.
- N이 1이라면 주사위가 1개이므로 전체 합 중에서 총 6면 중 가장 큰 한 면 빼주면 된다. 또는, 주사위 숫자를 정렬하여 5개의 합을 구한다.
- N이 1일 아닐 경우에는 한 면, 두 면, 세 면이 보일 경우를 나눈다.
- 한 면일 경우는 총 6면 중 최솟값을 찾아 최솟값 × 한 면이 보일 경우의 갯수를 result에 더한다.
- 두 면일 경우는 서로 이어지는 면이기 때문에 주사위의 i번째 값과 j번째 값의 합이랑 min값 중 최소인 값을 가지고 두 면이 보일 경우의 갯수와 곱하여 result에 더한다. (여기서 j + i != 5인 것은 서로 이어지지 않고 떨어져 있는 한 면이다.)
- 마지막으로 세 면일 경우는 아래 그림과 같이 A와 F 중 작은 값, B와 E 중 작은 값, C와 D중 작은 값의 합을 구하여 두 면이 보일 경우의 갯수를 곱하여 result에 더하여 반환한다.
Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long N = Integer.parseInt(br.readLine());
long result = 0; // 결과
int[] dice = new int[6]; // 주사위 숫자 담은 배열
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < 6; i++) {
dice[i] = Integer.parseInt(st.nextToken());
}
if (N == 1) { // 주사위 갯수가 1개일 때
Arrays.sort(dice);
for (int i = 0; i < 5; i++) {
result += dice[i];
}
System.out.println(result);
} else {
long one = (N - 2) * (5 * N - 6); // 한 면이 보일 경우
long two = 8 * N - 12; // 두 면이 보일 경우
long three = 4; // 세 면이 보일 경우
// 한 면일 경우
long min = dice[0];
for (int i = 1; i < dice.length; i++) {
min = Math.min(min, dice[i]);
}
result += min * one;
// 두 면일 경우
min = Long.MAX_VALUE;
for (int i = 0; i < dice.length; i++) {
for (int j = i + 1; j < dice.length; j++) {
// 두 면 서로 반대편에 있을 경우 제외
// (= 옆으로 이어져 있지 않은 경우 제외)
if (j + i != 5) {
min = Math.min(min, dice[i] + dice[j]);
}
}
}
result += min * two;
// 세 면일 경우
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += Math.min(dice[i], dice[5 - i]);
}
result += sum * three;
System.out.println(result);
}
}
}
반응형
'Algorithm > 백준' 카테고리의 다른 글
[백준_16234] 인구 이동 (0) | 2023.01.17 |
---|---|
[백준_16401] 과자 나눠주기 (1) | 2023.01.15 |
[백준_14235] 크리스마스 선물 (0) | 2023.01.08 |
[백준_15904] UCPC는 무엇의 약자일까? (1) | 2023.01.06 |
[백준_1260] DFS와 BFS (0) | 2023.01.05 |