구현 문제이다.
3차원의 주사위를 2차원의 평면에서 굴려가며 각 면의 숫자를 계산하는 방식이다.
한번 이 방법을 알아두면 나중에는 좀 겁이 덜 나게 풀 수 있을 것 같다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Main {
private static int n, m, x, y, k;
private static int[][] map;
private static int[] dirList;
private static final int[] dx = {0, 0, 0, -1, 1};
private static final int[] dy = {0, 1, -1, 0, 0};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
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());
k = Integer.parseInt(st.nextToken());
map = new int[n][m];
dirList = new int[k];
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++) {
dirList[i] = Integer.parseInt(st.nextToken());
}
solution(new Dice());
}
private static void solution(Dice dice) {
int dir, nx = x, ny = y;
for (int i = 0; i < k; i++) {
dir = dirList[i];
if (!isValid(nx + dx[dir], ny + dy[dir])) continue;
nx = nx + dx[dir];
ny = ny + dy[dir];
dice.turn(dir);//주사위를 움직인다.
//이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다.
if (map[nx][ny] == 0) map[nx][ny] = dice.getNum(7 - dice.up);
//0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.
else {
dice.setNum(7 - dice.up, map[nx][ny]);
map[nx][ny] = 0;
}
System.out.println(dice.getNum(dice.up));
}
}
private static boolean isValid(int x, int y) {
return x >= 0 && y >= 0 && x < n && y < m;
}
}
class Dice {
int[] nums;
int up, right, front;
Dice() {
nums = new int[6];
up = 1;
right = 3;
front = 5;
}
void turn(int dir) {
int temp = up;
switch (dir) {
case 1://동(우)
up = 7 - right;//왼쪽에있는면을 맨위로 올림(7-오른쪽)
right = temp;
break;
case 2://서(좌)
up = right;//오른쪽에 있는면을 맨위로 올림
right = 7 - temp;
break;
case 3://북(상)
up = front;//앞쪽에 있는면이 위로(위의방향으로 굴러가니깐)
front = 7 - temp;
break;
case 4://남(하)
up = 7 - front;//앞에있는면의 반대편면이 맨앞으로 감(7-뒷쪽)
front = temp;
break;
}
}
void setNum(int num, int value) {
nums[num - 1] = value;
}
int getNum(int num) {
return nums[num - 1];
}
}
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/001.gif)
위의 코드에서 중요하게 볼 부분은 class Dice에서 void turn(int dir)메소드이다.
코드를 살펴보면 정반대편 면의 값은 7-해당면을 하면 값이 나온다.
위 그림의 예로 보면 바닥면을 구하면, 7-up = 7-1 = 6 이다.
테스트케이스1을 예로 잡았다.
자 그럼 굴려보겠다.
굴리기 전을 A, 굴리고 난 후를 B라고 하겠다.
upA=1, frontA=5, rightA=3에서
case 4의 계산식대로 대입해보면 아래와 같다.
upB=7-front=7-5 =2 (앞쪽의 있는면의 반대편면, 즉 뒷쪽의 면이 윗면으로 올라온다.)
frontB=temp=이전up=1
그리고 rightB는 위아래로 굴리는경우 변함이 없으므로 계속 3이다.
따라서
upB=2, frontB=1, rightB=3
이러한 방식대로 이루어져있다. 다른 경우도 모두 이와 마찬가지로 주사위를 굴릴때 규칙성을 찾아내는것이 중요한 관건이다.
![](https://t1.daumcdn.net/keditor/emoticon/face/large/026.png)
코드 출처 : https://leveloper.tistory.com/88
주사위 : http://www.magicmgmt.com/gary/dice/one_die_image.html
반응형
'코딩테스트 > Java' 카테고리의 다른 글
[JAVA] 백준 드래곤 커브 (0) | 2021.06.03 |
---|---|
[JAVA] 백준 테트로미노 (0) | 2021.06.01 |
[JAVA] 백준 연구소 DFS+BFS (3) | 2021.05.10 |
[JAVA] 백준 후위표기식 (0) | 2021.05.04 |
[JAVA] 백준 마법사 상어와 파이어볼 (0) | 2021.04.29 |