문제 풀이 날짜: 2023.09.07
포스트 작성일: 2023.09.11
* 학습 목적으로 작성하는 글입니다. 풀이가 정석적이지 못할 수도 있습니다.
문제 출처
백준 온라인 저지 14499번: 주사위 굴리기 (골드4)
키워드
구현, 시뮬레이션
풀이 접근법
- 주사위를 굴렸을 때 다음 눈에 해당하는 좌표가 어디인지를 구하는 게 중요하며, 구현하기도 쉽지 않다. 배열 값은 물리적으로(?) 떨어져 있어도 실제 주사위 상으로는 이어져있기 때문이다.
- 여기서 주사위 배열을 1차원 배열로 선언하고, 각 방향으로 밀었을 때 숫자가 어떻게 변화하는 지를 switch문으로 대입해준다. 동, 서, 남, 북 4가지 방향으로 주사위를 밀었을 때 주사위의 어느 눈이 어느 위치로 옮겨가는 지만 지정해주면 된다. (경우의 수가 많지 않기 때문에 충분히 하드코딩을 시도해볼 수 있다.)
- 주의1 : 범위를 벗어나지 않고 굴릴 수 있는 경우에만 주사위 값을 옮겨주어야 하며, 그 때에만 출력을 진행해야 한다.
- 주의2 : 입력 표기가 (x, y)이지만 사실상 (row, col) 순서로 들어온다!!
- 따라서 row에 x를, col에 y를 대입하거나 입력 순서를 반대를 받자.
코드
import java.awt.Point;
import java.io.*;
import java.util.*;
public class Main {
private static final int UPPER = 3;
private static final int LOWER = 6;
private static int N;
private static int M;
private static int[] dice;
private static int[][] map;
private static int[] dr = {0, 0, -1, 1}; //동, 서, 북, 남
private static int[] dc = {1, -1, 0, 0};
private static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
map = new int[N][M];
dice = new int[LOWER + 1]; //인덱스 0은 사용하지 않음, 처음엔 모두 0
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());
}
}
//명령어 받기
int mapR = y;
int mapC = x;
st = new StringTokenizer(br.readLine(), " ");
for(int i = 0; i < K; i++) {
int dir = Integer.parseInt(st.nextToken());
Point moved = moveDice(dir, mapR, mapC);
if(moved != null) { //주사위를 굴렸다면 지도 좌표 갱신
mapR = moved.y;
mapC = moved.x;
}
}
System.out.print(sb);
}
private static Point moveDice(int dir, int mapR, int mapC) {
int nr = mapR + dr[dir - 1];
int nc = mapC + dc[dir - 1];
if(!isValid(nr, nc)) {
return null;
}
//굴릴 수 있다면 주사위의 방향을 바꿔준다.
int temp = dice[UPPER];
switch(dir) {
case 1:
dice[3] = dice[4];
dice[4] = dice[6];
dice[6] = dice[2];
dice[2] = temp;
break;
case 2:
dice[3] = dice[2];
dice[2] = dice[6];
dice[6] = dice[4];
dice[4] = temp;
break;
case 3:
dice[3] = dice[5];
dice[5] = dice[6];
dice[6] = dice[1];
dice[1] = temp;
break;
case 4:
dice[3] = dice[1];
dice[1] = dice[6];
dice[6] = dice[5];
dice[5] = temp;
break;
}
if(map[nr][nc] == 0) {
map[nr][nc] = dice[LOWER];
} else {
//0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며,
//칸에 쓰여 있는 수는 0이 된다.
dice[LOWER] = map[nr][nc];
map[nr][nc] = 0;
}
//주의: 굴릴 수 없다면 출력하지 않는다.
sb.append(dice[UPPER]).append("\n");
return new Point(nc, nr);
}
private static boolean isValid(int r, int c) {
return (r > -1 && c > -1 && r < N && c < M);
}
}
참고한 링크
https://loosie.tistory.com/763
https://developer-ellen.tistory.com/118
'Study > Problem Solving' 카테고리의 다른 글
[백준 / Java] 1062번: 가르침 (골드4) (0) | 2023.09.30 |
---|---|
[백준 / Java] 11591번: Mootube (Silver) (골드5) (0) | 2023.09.11 |
[백준 / Java] 2613번: 숫자구슬 (골드2) (0) | 2023.09.11 |
[백준 / Java] 16401번: 과자 나눠주기 (실버2) (0) | 2023.09.11 |
[백준 / Java] 15683번: 감시 (골드4) (0) | 2023.09.11 |