2116번: 주사위 쌓기
첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는
www.acmicpc.net
문제
천수는 여러 종류의 주사위를 가지고 쌓기 놀이를 하고 있다. 주사위의 모양은 모두 크기가 같은 정육면체이며 각 면에는 1부터 6까지의 숫자가 하나씩 적혀있다. 그러나 보통 주사위처럼 마주 보는 면에 적혀진 숫자의 합이 반드시 7이 되는 것은 아니다.
주사위 쌓기 놀이는 아래에서부터 1번 주사위, 2번 주사위, 3번 주사위, … 의 순서로 쌓는 것이다. 쌓을 때 다음과 같은 규칙을 지켜야 한다: 서로 붙어 있는 두 개의 주사위에서 아래에 있는 주사위의 윗면에 적혀있는 숫자는 위에 있는 주사위의 아랫면에 적혀있는 숫자와 같아야 한다. 다시 말해서, 1번 주사위 윗면의 숫자는 2번 주사위 아랫면의 숫자와 같고, 2번 주사위 윗면의 숫자는 3번 주사위 아랫면의 숫자와 같아야 한다. 단, 1번 주사위는 마음대로 놓을 수 있다.
이렇게 쌓아 놓으면 긴 사각 기둥이 된다. 이 사각 기둥에는 4개의 긴 옆면이 있다. 이 4개의 옆면 중에서 어느 한 면의 숫자의 합이 최대가 되도록 주사위를 쌓고자 한다. 이렇게 하기 위하여 각 주사위를 위 아래를 고정한 채 옆으로 90도, 180도, 또는 270도 돌릴 수 있다. 한 옆면의 숫자의 합의 최댓값을 구하는 프로그램을 작성하시오.
입력
첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는 주사위의 전개도에서 A, B, C, D, E, F 의 순서로 입력된다. 입력되는 숫자 사이에는 빈 칸이 하나씩 있다. 주사위의 개수는 10,000개 이하이며 종류가 같은 주사위도 있을 수 있다.
![](https://blog.kakaocdn.net/dn/bcw4sm/btruyNKa3wy/13xfjoaHxBTKrRU8EY2u8k/img.png)
그림 1
출력
첫줄에 한 옆면의 숫자의 합이 가장 큰 값을 출력한다.
풀이
/*
* 입력
* 1. 주사위의 개수
* 2. 주사위의 종류
* 출력
* 1. 한 옆면의 숫자 합이 가장 큰 값
* 조건
* 1. 아래 있는 주사위와 위에 있는 주사위가 같은 숫자로 맞붙어야 한다
* 2. 쌓은 채로 돌려서 큰 합을 구한다
* 3. 주사위는 보통의 것과 다르게 생김
*
* >> 재귀로 최댓값 구하기
*/
모든 경우의 수를 따지는 브루트포스 문제다 재귀를 이용해 풀었다
코드
package com.ssafy.boj;
import java.util.*;
import java.io.*;
public class g4_2116_주사위쌓기 {
static int N, top, sum;
static int[][] dice;
static boolean[] check;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//주사위의 개수
N = Integer.parseInt(br.readLine());
dice = new int[N][6];
check = new boolean[7];
//주사위의 종류
for(int i = 0; i<N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for(int j = 0; j<6; j++) {
dice[i][j] = Integer.parseInt(st.nextToken());
}
}
int max = 0;
//시작 숫자 1부터 6까지 고르기
for(int i = 1; i<=6; i++) {
sum = 0;
//제일 바닥 숫자 방문 체크
check[i]=true;
dice(0, i);
max = Math.max(max, sum);
}
System.out.println(max);
}
private static void dice(int cnt, int bottom) {
//옆면에서 더할 숫자
int num = 0;
//cnt가 N이면 방문 체크 초기화하고 return
if(cnt==N) {
check[bottom] = false;
return;
}
//윗면 숫자 구하기
for(int i = 0; i<6; i++) {
//바닥 숫자의 index 구하기
if(bottom == dice[cnt][i]) {
//a-f b-d c-e 0-5 1-3 2-4
//if 여섯개 쓰면 오래 걸릴 것 같아서 나눔(최대 세 번)
//위에서부터 0~5 순서
if(i<3) {
if(i<2) {
if(i==0) top = dice[cnt][5];
else top = dice[cnt][3];
} else top = dice[cnt][4];
} else {
if(i<5) {
if(i==3) top = dice[cnt][1];
else top = dice[cnt][2];
} else top = dice[cnt][0];
}
}
}
//윗면 숫자 방문 체크
check[top] = true;
//아랫면와 윗면에 있는 숫자를 제외한 옆면 중에 가장 큰 수 더하기
for(int i = 0; i<6; i++) {
//윗면과 아랫면 제외
if(check[dice[cnt][i]]) continue;
//남은 숫자들 중에 큰 값 저장
else num = Math.max(dice[cnt][i], num);
}
//sum에 저장
sum += num;
//아랫면 더는 사용하지 않기 때문에 방문 체크 초기화
check[bottom] = false;
//윗면이 바닥으로 간 상태로 다음 주사위 탐색
dice(cnt+1, top);
}
}
결과
#자바 #java #boj #백준 #알고리즘
'알고리즘 > BOJ' 카테고리의 다른 글
[java][boj][s4] 10157. 자리 배정 (0) | 2022.02.28 |
---|---|
[java][boj][s1] 2527. 직사각형 (0) | 2022.02.28 |
[java][boj][s2] 2304. 창고 다각형 (0) | 2022.02.26 |
[java][boj][s4] 10158. 개미 (0) | 2022.02.26 |
[java][boj][s4] 2477. 참외밭 (0) | 2022.02.25 |