문제 이해
처음에는 [주사위 윗면: map과 붙어 있는 면]이라고 이해하여 문제를 풀었는데, 당연히 출력 예제처럼 답이 나오지 않았다.
도저히 이해되지 않아서 직접 주사위를 만들어 굴려보고 깨달았다.
사실 문제를 제대로 읽어보면 친절하게 주사위 윗면이 1번이라고 나와 있다.. 문제를 제대로 읽자.
주사위 구현
주사위를 무조건 3차원으로 구현해야 된다고 생각하여 시간을 많이 소비했다.
3차원까지 가지 않고, 주사위 전개도를 이용하면 쉽게 구현할 수 있다. (전개도를 괜히 그려준 것이 아니다..)
주사위가 map 안에서 구를 수 있다면 주사위의 값을 평면 위에서 옮겨주면 된다.
이 문제는 주사위만 구현할 줄 알면 그 외의 요소는 그래프 탐색과 유사하다.
동쪽과 서쪽은 실제 주사위를 만들어서 굴리다 보면 이해가 가능하다.
주사위 윗면은 1번, 주사위 밑면은 6번인 것을 기억하자.
public class Main { private static int n; private static int m; private static int x; private static int y; private static int[][] map; private static int[] dice; private static final int[] dx = {0, 0, -1, 1}; // 동 서 북 남 private static final int[] dy = {1, -1, 0, 0}; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringBuilder sb = new StringBuilder(); StringTokenizer 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()); int k = Integer.parseInt(st.nextToken()); map = new int[n][m]; dice = new int[7]; 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()); } } st = new StringTokenizer(br.readLine()); for (int i = 0; i < k; i++) { int command = Integer.parseInt(st.nextToken()); roll(command, sb); } System.out.print(sb.deleteCharAt(sb.length() - 1)); br.close(); } private static void roll(int command, StringBuilder sb) { int nx = x + dx[command - 1]; int ny = y + dy[command - 1]; if (nx >= 0 && nx < n && ny >= 0 && ny < m) { int tmp = dice[6]; // dice[6] 값이 덮어 쓰여지지 않도록 tmp에 따로 저장해둔다. (x, y 값 서로 바꿀 때 tmp 사용하는 것과 유사함) switch (command) { case 1: // 동 dice[6] = dice[3]; dice[3] = dice[1]; dice[1] = dice[4]; dice[4] = tmp; break; case 2: // 서 dice[6] = dice[4]; dice[4] = dice[1]; dice[1] = dice[3]; dice[3] = tmp; break; case 3: // 북 dice[6] = dice[5]; dice[5] = dice[1]; dice[1] = dice[2]; dice[2] = tmp; break; case 4: // 남 dice[6] = dice[2]; dice[2] = dice[1]; dice[1] = dice[5]; dice[5] = tmp; break; } x = nx; y = ny; if (map[x][y] == 0) { map[x][y] = dice[6]; // 밑면 값 저장 } else { dice[6] = map[x][y]; map[x][y] = 0; } sb.append(dice[1]).append("\n"); // 윗면 출력 } } }
약 3일의 시간이 걸린 주사위 굴리기 끝.