문제
https://www.acmicpc.net/problem/14499
풀이
주사위의 전개도를 그려보고 이동했을 때 각 면이 어느 위치로 바뀌는지 생각하고 구현하면 되는 문제.
다음과 같이 접근하였다.
처음 주사위는 6면은 다음을 가리키고 있다. (참고로 문제 본문에서 제시하는 면의 숫자와 다르다. 본인 임의로 배치한 것)
상 : 1 , 하 : 4
좌 : 2 , 우 : 5
앞 : 3 , 뒤 : 6
각 면을 가리키는 내용을 인덱스 순서대로 배열에 저장한다. (상, 좌, 앞, 하, 우, 뒤)
그리고 한번 굴리는 것을 시뮬레이션 해보자.
기본상태에서 동쪽(1)으로 굴리면 다음과 같이 변경된다.
상 : 1 -> 2 , 하 : 4 -> 5
좌 : 2 -> 4 , 우 : 5 -> 1
앞 : 3 -> 3 , 뒤 : 6 -> 6
기본상태에서 서쪽(2)으로 굴리면 다음과 같이 변경된다.
상 : 1 -> 5 , 하 : 4 -> 2
좌 : 2 -> 1 , 우 : 5 -> 4
앞 : 3 -> 3 , 뒤 : 6 -> 6
기본상태에서 북쪽(3)으로 굴리면 다음과 같이 변경된다.
상 : 1 -> 3 , 하 : 4 -> 6
좌 : 2 -> 2 , 우 : 5 -> 5
앞 : 3 -> 1 , 뒤 : 6 -> 4
기본상태에서 남쪽으로 굴리면 다음과 같이 변경된다.
상 : 1 -> 6 , 하 : 4 -> 3
좌 : 2 -> 2 , 우 : 5 -> 5
앞 : 3 -> 1 , 뒤 : 6 -> 4
면을 굴려보면 두개의 면은 고정되고 (회전축으로 생각) 4개의 면이 바뀌는 것을 알 수 있는데.
초기 상태에서 어떤 면을 순차적으로 바꾸면 원래로 돌아옴을 알 수 있다.
즉 면의 정보가 저장된 처음 배열에서 각 원소를 바꾸면 각 방향으로 이동했을 때 각 면이 가리키는 내용을 알 수 있다.
코드를 보면 무슨 내용인지 알 수 있을 것이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_14499 {
static final int DICE_NUMBER = 6;
// 위:1 , 아래:4, 좌:2, 우:5, 앞:3, 뒤:6
static int[] dice = new int[DICE_NUMBER+1];
static int N, M, x, y, K;
static StringTokenizer st;
static int[][] map;
static int[] dy = {0,1,-1,0,0};
static int[] dx = {0,0,0,-1,1};
public static void main(String[] args) throws IOException {
Application();
}
public static void Application() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
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());
}
}
st = new StringTokenizer(br.readLine());
for (int k = 0; k < K; k++) {
switch(Integer.parseInt(st.nextToken())) {
case 1:
moveEast();
break;
case 2:
moveWest();
break;
case 3:
moveNorth();
break;
case 4:
moveSouth();
break;
}
}
}
public static void simulate() {
if(map[x][y] != 0) {
dice[4] = map[x][y];
map[x][y] = 0;
} else {
map[x][y] = dice[4];
}
}
public static void moveEast() {
if(isMove(x,y,1)) {
swap(1,4); swap(1,2); swap(4,5);
simulate();
getDiceUpside();
}
}
public static void moveWest() {
if(isMove(x,y,2)) {
swap(2,5); swap(1,2); swap(4,5);
simulate();
getDiceUpside();
}
}
public static void moveNorth() {
if(isMove(x,y,3)) {
swap(3,6); swap(1,3); swap(4,6);
simulate();
getDiceUpside();
}
}
public static void moveSouth() {
if(isMove(x,y,4)) {
swap(4,1); swap(1,3); swap(4,6);
simulate();
getDiceUpside();
}
}
public static void swap(int x, int y) {
int temp = dice[y];
dice[y] = dice[x];
dice[x] = temp;
}
public static boolean isMove(int inputX, int inputY, int direction) {
int nx = inputX + dx[direction];
int ny = inputY + dy[direction];
if(nx >=0 && nx < N && ny >=0 && ny < M) {
x = nx;
y = ny;
return true;
}
return false;
}
public static void getDiceUpside() {
System.out.println(dice[1]);
}
}
'Problem Solving > CT-Java' 카테고리의 다른 글
[SWEA/구현] 무선 충전 [모의 SW 역량테스트] - 자바 (0) | 2022.08.27 |
---|---|
[백준/BFS] 16236: 아기상어 - 자바 (0) | 2022.08.27 |
[백준/BFS] 2206: 벽 부수고 이동하기 - 자바 (0) | 2022.08.27 |
[백준/BFS] 3055: 탈출 - 자바 (0) | 2022.08.27 |
[SWEA/구현] 1289: 원재의 메모리 복구하기 - 자바 (0) | 2022.08.22 |