본문 바로가기
공부 정리/백준

[백준] 자바 1041 주사위

by 경적필패. 2021. 2. 17.
반응형

문제

출처 : https://www.acmicpc.net/problem/1041

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

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

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

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

입력

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

출력

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


테스트케이스

 

초록색 입력/ 검은색 출력


접근

n^3개의 만큼 정육면체 주사위를 쌓아서 보이는 면의 수가 최소가 되게끔 하는 문제입니다.

 

주사위가 한 개일 때는 전체 값에서 최댓값을 빼주면 되고,

주사위가 1개 초과일 때부터는 최솟값을 찾아서 계산해주면 됩니다.

여기서 주의하여야 할 점이 주사위가 보이는 면의 반대쪽은 절대 보일 수 없다는 점입니다. ex(a가 보이면 f는 안보임)

 

주사위 개수별로 보여야 하는 면의 개수의 점화식을 세워 답을 낼 수 있었습니다.

하나의 면짜리 주사위 : (4 * (n - 1) * (n - 2) + (n - 2) * (n - 2))

두 개의 면짜리 주사위 :  (((n-2) * 2 * 4) + (n-1) * 4 * 2)

세 개의 면짜리 주사위 : 4

*하나의 면짜리에는 6개의 값 중 최솟값만 들어가면 되고

*두 개의 면짜리에는 6개의 값 중 최솟값 + 그다음 최솟값

*세 개의 면짜리에는 6개의 값 중 최솟값 + 그다음 최솟값 + 그 다음다음 최솟값

(그러나 a, f / b, e / c, d 면을 생각해야 함)


코드

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

public class Main {

	/*
 	1041 problem 주사위
	*/

	public static void main(String[] args) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		long n = Integer.parseInt(br.readLine());
		int arr[] = new int[6];
		long ans = 0;
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		for(int i=0; i<6; i++) {
			arr[i] = Integer.parseInt(st.nextToken());
		}
		long first = Math.min(arr[0], arr[5]);
		long second = Math.min(arr[1], arr[4]);
		long third = Math.min(arr[2], arr[3]);
		
		//first,second,third를 정렬하기 위함
		long sortArr[] = new long[3];
		sortArr[0] = first;
		sortArr[1] = second;
		sortArr[2] = third;
		Arrays.sort(sortArr);
		first = sortArr[0];
		second = sortArr[1];
		third = sortArr[2];
		
		int sum = 0;
		int max = 0;
		if(n == 1) {
			for(int i=0; i<6; i++) {
				sum += arr[i];
			}
			for(int i=0; i<6; i++) {
				max = Math.max(max, arr[i]);
			}
			ans = sum - max;
		}
		else {
			ans += (4 * (n - 1) * (n - 2) + (n - 2) * (n - 2)) * first;
			ans += (((n-2) * 2 * 4) + (n-1) * 4 * 2) / 2 * first;
			ans += 4 * first;
			
			ans += (((n-2) * 2 * 4) + (n-1) * 4 * 2) / 2  * second;
			ans += 4 * second;
			
			ans += 4 * third;
		}
		bw.write(String.valueOf(ans));
		bw.flush();
		bw.close();
	}
}

주의

  • int * int를 long에 넣으면 안 됨.
  • n = 1일 때 따로 지정
  • (AF, BE, CD)에서도 최솟값을 구해서 정렬해줘야 함.
반응형

'공부 정리 > 백준' 카테고리의 다른 글

[백준] 자바 1931 회의실 배정  (0) 2021.02.19
[백준] 자바 1439 뒤집기  (0) 2021.02.18
[백준] 자바 1105 팔  (0) 2021.02.16
[백준] 자바 1449 수리공 항승  (0) 2021.02.15
[백준] 자바 2751 수 정렬하기 2  (0) 2021.02.15

댓글