문제
N x M 지도 위에서 주사위를 굴리는 명령이 주어질 때, 규칙에 따라 주사위를 이동시키며 매번 윗면의 값을 출력하라.
입력
첫째 줄에 N, M, 주사위 위치 (x, y), 명령 수 K가 주어진다. 이후 지도와 명령이 주어진다. 명령: 1(동), 2(서), 3(북), 4(남).
출력
각 명령 후 주사위 윗면의 값을 출력한다. 범위 밖이면 무시.
예제
| 입력 | 출력 |
|---|---|
4 2 0 0 8 0 2 3 4 5 6 7 8 4 4 4 1 3 3 3 2 | 0 0 3 0 0 8 6 3 |
풀이
주사위의 6면(up, down, front, back, left, right)을 객체로 관리하며, 방향별 굴리기 연산을 시뮬레이션한다.
- Dice 클래스로 6면의 값을 관리한다
- 각 방향으로 굴릴 때 면의 값을 순환 교환한다 (예: 동쪽 → up→right→down→left→up)
- 이동 후 바닥이 0이면 주사위 바닥면 값을 지도에 복사하고, 0이 아니면 지도 값을 주사위 바닥에 복사 후 지도를 0으로 만든다
- 매번 윗면 값을 출력한다
핵심 아이디어: 주사위의 회전을 면 값의 순환 교환으로 구현하면, 6개의 변수만으로 모든 상태를 관리할 수 있다.
코드
package ASP_study.day299;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Day280BOJ14499주사위구현 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringBuilder sb = new StringBuilder();
static StringTokenizer st;
static int N, M, x, y, K;
static int[][] map;
static int[] dx = { 0, 0, 0, -1, 1 };
static int[] dy = { 0, 1, -1, 0, 0 };
public static void main(String[] args) throws Exception {
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
x = Integer.parseInt(st.nextToken());
y = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new int[N][M];
for (int i = 0; i < N; ++i) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; ++j) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
Dice dice = new Dice();
st = new StringTokenizer(br.readLine());
for (int i = 0; i < K; ++i) {
int curDir = Integer.parseInt(st.nextToken());
x += dx[curDir];
y += dy[curDir];
if (!isIn(x, y)) {
x -= dx[curDir];
y -= dy[curDir];
continue;
}
if (curDir == 1)
dice.right();
else if (curDir == 2)
dice.left();
else if (curDir == 3)
dice.up();
else
dice.down();
if (map[x][y] == 0) {
map[x][y] = dice.down;
} else {
dice.down = map[x][y];
map[x][y] = 0;
}
sb.append(dice.up + "\n");
}
System.out.println(sb.toString());
}
static boolean isIn(int r, int c) {
return r >= 0 && r < N && c >= 0 && c < M;
}
static class Dice {
int up;
int down;
int front;
int back;
int left;
int right;
public void right() {
int tmp = right;
right = up;
up = left;
left = down;
down = tmp;
}
public void left() {
int tmp = right;
right = down;
down = left;
left = up;
up = tmp;
}
public void up() {
int tmp = up;
up = front;
front = down;
down = back;
back = tmp;
}
public void down() {
int tmp = up;
up = back;
back = down;
down = front;
front = tmp;
}
}
}복잡도
- 시간: O(K + N * M)
- 공간: O(N * M)