일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 이클립스
- 코딩테스트
- SQL
- 해킹실습
- SQL 문법
- 토이프로젝트
- 리눅스마스터 2급 2차
- SQL 정리
- c언어
- 문법
- 기초
- MySQL
- 알고리즘
- 데이터베이스
- 데이터프로그래밍
- 문제풀이
- 엘라스틱서치
- 프로그래밍
- 프로그래머스
- 위클리챌린지
- 백준
- 스파크
- 스프링
- 필기
- 스프링부트
- 오라클
- 빅데이터
- 자바
- 모의해킹
- 파이썬
- Today
- Total
개발일기
백준 1041번 JAVA 풀이 - 주사위 본문
문제 링크 : https://www.acmicpc.net/problem/1041
1041번: 주사위
첫째 줄에 N이 주어진다. 둘째 줄에 주사위에 쓰여 있는 수가 주어진다. 위의 그림에서 A, B, C, D, E, F에 쓰여 있는 수가 차례대로 주어진다. N은 1,000,000보다 작거나 같은 자연수이고, 쓰여 있는 수
www.acmicpc.net
+---+
| D |
+---+---+---+---+
| E | A | B | F |
+---+---+---+---+
| C |
+---+
주사위는 위와 같이 생겼다. 주사위의 여섯 면에는 수가 쓰여 있다. 위의 전개도를 수가 밖으로 나오게 접는다.
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보다 작거나 같은 자연수이다.
출력
첫째 줄에 문제의 정답을 출력한다.


# 문제 풀이
주사위를 쌓았을 때 3면이 보이는 주사위, 2면이 보이는 주사위, 1면이 보이는 주사위의 갯수에는 규칙이 있다.
만약 주사위를 3^3승 총 27개를 가지고 있어서 정육면체를 만든다고 할 때 3개의 면을 보이는 주사위의 갯수는 4개이다.
여기서 다시한번 생각해보면 제일 윗면의 모서리만 3개의 면을 보여주고 있기 때문에 주사위를 몇개 쌓아도 3개의 면을 보여주는 주사위의 갯수는 4개로 변함이 없다.
2개의 면을 보이는 주사위 갯수를 파악해보면 맨 윗층을 제외한 층들은 모서리 총 4개 * (층수 - 1) 만큼이며
맨 위층은 N이 3이면 1 * 4, N이 4이면 2 * 4 이다. N 이 2일 경우 맨 윗층의 주사위는 모두 3개의 면을 보여주기 때문에 0 * 4인 0이 된다.
따라서 4 * (N - 1) + (N - 2) * 4 로 수식을 정리할 수 있으며 4 * ((2 * N) - 3) 으로 정리할 수 있다.
나머지 한면만 보이는 주사위의 갯수는 (N - 2)(N - 1) * 4 로 식을 정리할 수 있다. N - 2 는 한줄에 양 모서리를 제외한 가운데에 오는 주사위의 갯수를 의미하며 N -1 은 맨 위층을 뺀 나머지 층을 이야기 한다. 따라서 N 이 3일경우 1 * 2 * 4로 맨 앞면의 주사위 갯수인 2 * 총 4면 으로 주사위의 갯수를 구할 수 있다.
그리고 맨 윗층에 가운데 1개를 더해주어야 한다. N이 3이라면 1, N이 4라면 4, N이 5라면 9개 가 된다. (N - 2)*(N - 2) 개를 추가적으로 더해주면 된다.
정리하자면
3개의 면이 보이는 주사위 : 4개
2개의 면이 보이는 주사위 : 4 * ((2 * N) -3) = 8 * N - 12
1개의 면이 보이는 주사위 : (N - 2)(N - 1) * 4 + (N - 2)(N - 2) = (N - 2) * (5 * N - 6)
로 정리할 수 있다.
이제 각 면들의 최소값을 구해야 한다.
3면이 보이는 주사위의 최소값은
D, C 중 작은값, E, B 중 작은 값, A, F 중 작은 값을 더하면 된다.
2면이 보이는 주사위의 최소값은
A 면을 기준으로 마주보는 F 면을 제외한 모든 면이기 때문에 하나씩 확인을 해야한다.
1면이 보이는 주사위의 최소값은 입력받은 배열에서 최소값을 출력하면 된다.
# 코드 설명
1. 3개의 면이 보이는 주사위의 최소값 구하기
static long find_min3(int[] arr){
long min = 0;
//0 - 5
min += (arr[0] < arr[5]? arr[0] : arr[5]);
//1 - 4
min += (arr[1] < arr[4]? arr[1] : arr[4]);
//2 - 3
min += (arr[2] < arr[3]? arr[2] : arr[3]);
return min;
}
서로 마주보는 면 중에 작은 수를 최소값 변수에 더하면 된다.
2. 2개의 면이 보이는 주사위의 최소값 구하기
static long find_min2(int[] arr){
long min = arr[0] + arr[1];
for(int i = 0; i < arr.length; i++){
for(int j = i + 1; j < arr.length; j++){
if(i + j == 5) continue;
if(min > arr[i] + arr[j]) min = arr[i] + arr[j];
}
}
return min;
}
처음 최소값을 0번째 값과 1번째 값을 더한 수를 최소값으로 지정한 후 2중 반복문을 통해 모든 case를 체크한다.
여기서 i + j의 값이 5가 되는 경우는 서로 마주보는 case기 때문에 이땐 continue로 바로 넘어간다.
3. 1개의 면이 보이는 주사위의 최소값 구하기
static long find_min1(int[] arr){
long min = arr[0];
for(int i = 0; i < arr.length; i++){
if(arr[i] < min) min = arr[i];
}
return min;
}
반복문으로 모든 면을 탐색하면서 최소값을 출력하면 된다.
※ 주의사항
사전에 3개의 면은 4개, 2개의 면은 8 * n - 12개 , 1개의 면은 (n - 2) * (5 * n - 6) 개 로 정했지만 주사위가 1개 입력될 경우 3개의 면이 보이는 주사위는 4개가 될 수 없다. 따라서 입력한 n이 1개인지 아닌지를 판단해야한다.
if(n != 1){
long min_3 = find_min3(dice);
long min_2 = find_min2(dice);
long min_1 = find_min1(dice);
long sum = 4 * min_3;
sum += (8 * n - 12) * min_2;
sum += (n - 2) * (5 * n - 6) * min_1;
System.out.println(sum);
}
else{
System.out.println(one_dice(dice));
}
# 전체 코드
import java.util.*;
public class Main_1041 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int[] dice = new int[6];
long n = sc.nextInt();
for(int i = 0; i < dice.length; i++){
dice[i] = sc.nextInt();
}
if(n != 1){
long min_3 = find_min3(dice);
long min_2 = find_min2(dice);
long min_1 = find_min1(dice);
long sum = 4 * min_3;
sum += (8 * n - 12) * min_2;
sum += (n - 2) * (5 * n - 6) * min_1;
System.out.println(sum);
}
else{
System.out.println(one_dice(dice));
}
}
static long find_min3(int[] arr){
long min = 0;
//0 - 5
min += (arr[0] < arr[5]? arr[0] : arr[5]);
//1 - 4
min += (arr[1] < arr[4]? arr[1] : arr[4]);
//2 - 3
min += (arr[2] < arr[3]? arr[2] : arr[3]);
return min;
}
static long find_min2(int[] arr){
long min = arr[0] + arr[1];
for(int i = 0; i < arr.length; i++){
for(int j = i + 1; j < arr.length; j++){
if(i + j == 5) continue;
if(min > arr[i] + arr[j]) min = arr[i] + arr[j];
}
}
return min;
}
static long find_min1(int[] arr){
long min = arr[0];
for(int i = 0; i < arr.length; i++){
if(arr[i] < min) min = arr[i];
}
return min;
}
static long one_dice(int[] arr){
long min = 0;
long max = 0;
for(int i = 0; i < arr.length; i++){
min += arr[i];
if(max < arr[i]) max = arr[i];
}
return min - max;
}
}
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
백준 1353번 JAVA 풀이 - 합과 곱 (2) | 2022.06.22 |
---|---|
백준 1323번 JAVA 풀이 - 숫자 연결하기 (0) | 2022.06.20 |
백준 1235번 JAVA 풀이 - 학생번호 (0) | 2022.06.17 |
백준 1359번 JAVA 풀이 - 복권 (0) | 2022.06.16 |
백준 1072번 JAVA 풀이 - 게임 (0) | 2022.06.15 |