알고리즘/백준저지
백준저지 2116번 주사위 쌓기
anott
2021. 8. 26. 01:11
출처: https://www.acmicpc.net/problem/2116
2116번: 주사위 쌓기
첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는
www.acmicpc.net
제출 날짜: 2021년 8월 25일 수요일
생각
주사위의 윗면과 아랫면을 서로 연결해서 배열을 만들어 풀었다.
처음에는 옆면의 가장 큰 수가 무조건 6 또는 5라고 가정하고 풀었는데 틀렸다. 6과 5 모두 윗면과 아랫면에 사용되는 경우도 있는 것 같다. 4도 옆면이 될 수 있다는 가정을 넣으니 통과했다.
코드
//출처: 백준저지 2116번 주사위 쌓기 https://www.acmicpc.net/problem/2116
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ2116 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static int N, answer;
static int[][] dice;
public static void main(String[] args) throws IOException {
N = Integer.parseInt(br.readLine());
dice = new int[N][7]; // N개의 주사위. 1~6까지 해당 주사위 면의 반대편 면 저장
int[] input = new int[6];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 6; j++) { // 우선 주사위 하나 입력 받기
input[j] = Integer.parseInt(st.nextToken());
}
dice[i] = setDiceNum(input); // 해당 주사위의 윗면 아랫면 정리하기
}
answer = 0; // 답 0으로 초기화
for (int i = 1; i < 7; i++) {
findMax(0, dice[0][i], 0); // 0번째 주사위, 0번째 주사위의 6면 모두 확인, 옆면 합
}
System.out.println(answer); // 답 출력
}
private static int[] setDiceNum(int[] input) {
int[] dInput = new int[7];
// 입력 순서: A B C D E F
// 윗면과 해당 아랫면: AF(0,5) BD(1,3) CE(2,4)
dInput[input[0]] = input[5];
dInput[input[5]] = input[0];
dInput[input[1]] = input[3];
dInput[input[3]] = input[1];
dInput[input[2]] = input[4];
dInput[input[4]] = input[2];
return dInput; // 배열 정리 후 리턴
}
private static void findMax(int diceNum, int under, int sum) {
// 주사위 번호(0 ~ N-1), 아랫면, 옆면 합
if (diceNum == N) { // 마지막 주사위까지 올렸다면
answer = Math.max(answer, sum); // 더 큰 수 저장한 후 리턴
return;
}
int front = dice[diceNum][under]; // 윗면 구하기
if (under != 6 && front != 6) { // 윗면 아랫면 모두 6이 아니라면
findMax(diceNum + 1, front, sum + 6); // 가장 큰 옆면은 6
} else if (under != 5 && front != 5) { // 윗면 아랫면 모두 5도 아니라면
findMax(diceNum + 1, front, sum + 5); // 가장 큰 옆면은 5
} else { // 그 외의 경우는 무조건 4
findMax(diceNum + 1, front, sum + 4);
}
}
}