문제 탐색하기
간단한 시뮬레이션 문제이다. 문제에서 요구하는건 주사위를 지도위에 따라서 굴리고 지도 바깥으로 벗어나지 않을 때만 해당 주사위의 top을 출력하면 된다. 시간 복잡도는 O(M)으로 계산해볼 수 있다. 실제 연산에 드는 시간이 크지 않고 들어오는 M의 값에 따라서만 달라지면 된다.
주사위를 하나의 클래스로 생성하고 top, bottom, right, left, front, rear 이런 식으로 이름을 붙여서 돌리는 연산을 수행하였다.
이전에 문제를 풀었을 때는 위와 같이 하지 않고 주사위 자체도 2차원 배열로 설정하여 풀었었는데, 주사위에게 좌표 값을 입력해주지 않아도 되는 걸 생각해보면 위와 같은 방식이 구현할 때 어렵지 않고 효율적일 듯 하다.
이 때 연산의 종류와 상관없이 지도 바깥으로 벗어날 시 출력을 하지 않도록 구현하고, 만나는 칸이 0일 때와 그렇지 않을 때를 고려하면 답을 받을 수 있다.
조심해야하는건 다른 시뮬레이션(구현) 문제와 다르게 1, 2, 3, 4의 방향이 제각각이므로 dx, dy를 설정할 때 조심하면 된다.
코드 구현하기
1. 입력을 처리하고 2차원 배열에 숫자 지도를 나타낸다.
2. 명령에 따라서 주사위를 굴릴 수 있도록 한다.
3. 주사위가 이동할 때 경계 선 밖을 벗어나지 않는지 확인하고, 0일 때는 주사위에서 칸으로, 0이 아닐 때는 칸에서 주사위로 복사한다.
4. 주사위가 굴려진 후 top을 출력한다.
풀이
import java.util.*;
import java.io.*;
public class Main {
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
static void roll(int order, Dice dice) {
int nx = x + dx[order];
int ny = y + dy[order];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) {
return;
}
x = nx;
y = ny;
if (order == 1) {
rollEast(dice);
} else if (order == 2) {
rollWest(dice);
} else if (order == 3) {
rollNorth(dice);
} else {
rollSouth(dice);
}
dice.printTop();
}
static void rollEast(Dice dice) {
int temp = dice.right;
dice.right = dice.top;
dice.top = dice.left;
dice.left = dice.bottom;
if (map[x][y] == 0) {
dice.bottom = temp;
map[x][y] = dice.bottom;
} else {
dice.bottom = map[x][y];
map[x][y] = 0;
}
}
static void rollWest(Dice dice) {
int temp = dice.left;
dice.left = dice.top;
dice.top = dice.right;
dice.right = dice.bottom;
if (map[x][y] == 0) {
dice.bottom = temp;
map[x][y] = dice.bottom;
} else {
dice.bottom = map[x][y];
map[x][y] = 0;
}
}
static void rollNorth(Dice dice) {
int temp = dice.rear;
dice.rear = dice.top;
dice.top = dice.front;
dice.front = dice.bottom;
if (map[x][y] == 0) {
dice.bottom = temp;
map[x][y] = dice.bottom;
} else {
dice.bottom = map[x][y];
map[x][y] = 0;
}
}
static void rollSouth(Dice dice) {
int temp = dice.front;
dice.front = dice.top;
dice.top = dice.rear;
dice.rear = dice.bottom;
if (map[x][y] == 0) {
dice.bottom = temp;
map[x][y] = dice.bottom;
} else {
dice.bottom = map[x][y];
map[x][y] = 0;
}
}
static class Dice {
int top, bottom, left, right, front, rear;
public Dice() {
this.top = 0;
this.bottom = 0;
this.left = 0;
this.right = 0;
this.front = 0;
this.rear = 0;
}
void printTop() {
System.out.println(this.top);
}
@Override
public String toString() {
System.out.println("________________________");
return " " + front + " \n" + left + " " + top + " " + right + " \n " + rear + " \n " + bottom;
}
}
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};
static void printMap() {
System.out.println("_____________________________");
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
System.out.println("_____________________________");
}
public static void main(String[] args) {
FastReader fr = new FastReader();
N = fr.nextInt();
M = fr.nextInt();
x = fr.nextInt();
y = fr.nextInt();
K = fr.nextInt();
map = new int[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
map[i][j] = fr.nextInt();
}
}
Dice dice = new Dice();
for (int i = 0; i < K; i++) {
int now = fr.nextInt();
roll(now, dice);
}
}
}
'Problem Solving > BOJ' 카테고리의 다른 글
백준 17837번 : 새로운 게임 2 [Java] (0) | 2025.02.13 |
---|---|
백준 14890번 : 경사로 [Java] (0) | 2025.02.12 |
백준 1561번 : 놀이 공원 [Java] (0) | 2025.02.10 |
백준 12015번 : 가장 긴 증가하는 부분 수열 2 [Java] (0) | 2025.02.09 |
백준 2473번 : 세 용액 [Java] (1) | 2025.02.08 |