https://www.acmicpc.net/problem/14499
주어진 방법대로 주사위를 굴렸을 때 윗면에 써진 숫자를 구하는 문제입니다.
자세한 규칙은 문제 설명을 참고해 주세요.
주사위가 각 방향별로 회전하면 값의 위치가 어떻게 바뀌는지를 메서드로 작성합니다.
규칙은 아래와 같습니다.
- 초기 위치의 인덱스를 0, 1, 2, 3, 4, 5라고 가정했을 때 회전 시 평면 상에서의 각 면은 아래와 같이 변화한다.
- 동쪽 (direction = 1) → 3, 1, 0, 5, 4, 2
- 서쪽 (direction = 2) → 2, 1, 5, 0, 4, 3
- 북쪽 (direction = 3) → 4, 0, 2, 3, 5, 1
- 남쪽 (direction = 4) → 1, 5, 2, 3, 0, 4
private static int[] rotateDice(int[] dice, int direction) {
if (direction == 1) return new int[]{ dice[3], dice[1], dice[0], dice[5], dice[4], dice[2] };
if (direction == 2) return new int[]{ dice[2], dice[1], dice[5], dice[0], dice[4], dice[3] };
if (direction == 3) return new int[]{ dice[4], dice[0], dice[2], dice[3], dice[5], dice[1] };
return new int[]{ dice[1], dice[5], dice[2], dice[3], dice[0], dice[4] };
}
이동하지 않으면 출력하지 않습니다.
for (int movement: move) {
int nextX = currentDiceX + DX[movement];
int nextY = currentDiceY + DY[movement];
// 이동할 수 없는 경우 처리
if (nextX < 0 || nextX >= m || nextY < 0 || nextY >= n) continue;
// 다음 주사위의 지도 상 위치
currentDiceX = nextX;
currentDiceY = nextY;
// 주사위를 다음 좌표로 이동
dice = rotateDice(dice, movement);
if (map[currentDiceY][currentDiceX] == 0) {
map[currentDiceY][currentDiceX] = dice[5];
} else {
dice[5] = map[currentDiceY][currentDiceX];
map[currentDiceY][currentDiceX] = 0;
}
builder.append(dice[0] + "\n");
}
시작 좌표의 x, y 값에 주의합니다.
2차원 배열의 크기를 m열 n행으로 정의해야 지도 상에서의 x, y 값이 뒤집히지 않습니다.
그러나 m열 n행 (int[m][n]) 으로 처리할 경우 입력을 지도에 집어넣기가 다소 복잡해지므로 int[n][m]으로 처리하되 필요한 부분의 좌표를 뒤집어 처리하였습니다.
import java.util.*;
import java.io.*;
public class Main {
private final static int[] DX = { 0, 1, -1, 0, 0 };
private final static int[] DY = { 0, 0, 0, -1, 1 };
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringBuilder builder = new StringBuilder();
int[] nmxyk = Arrays.stream(reader.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int n = nmxyk[0], m = nmxyk[1], y = nmxyk[2], x = nmxyk[3];
int[][] map = new int[n][m];
int[] dice = new int[6];
// 지도 요소 입력
for (int i = 0; i < n; i++) map[i] = Arrays.stream(reader.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int[] move = Arrays.stream(reader.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int currentDiceX = x, currentDiceY = y;
for (int movement: move) {
int nextX = currentDiceX + DX[movement];
int nextY = currentDiceY + DY[movement];
// 이동할 수 없는 경우 처리
if (nextX < 0 || nextX >= m || nextY < 0 || nextY >= n) continue;
// 다음 주사위의 지도 상 위치
currentDiceX = nextX;
currentDiceY = nextY;
// 주사위를 다음 좌표로 이동
dice = rotateDice(dice, movement);
if (map[currentDiceY][currentDiceX] == 0) {
map[currentDiceY][currentDiceX] = dice[5];
} else {
dice[5] = map[currentDiceY][currentDiceX];
map[currentDiceY][currentDiceX] = 0;
}
builder.append(dice[0] + "\n");
}
System.out.print(builder.toString());
}
private static int[] rotateDice(int[] dice, int direction) {
if (direction == 1) return new int[]{ dice[3], dice[1], dice[0], dice[5], dice[4], dice[2] };
if (direction == 2) return new int[]{ dice[2], dice[1], dice[5], dice[0], dice[4], dice[3] };
if (direction == 3) return new int[]{ dice[4], dice[0], dice[2], dice[3], dice[5], dice[1] };
return new int[]{ dice[1], dice[5], dice[2], dice[3], dice[0], dice[4] };
}
}