목차
- 문제
- 내가 푼 방법
- 자바 코드
- 결과 및 회고
1. 문제
https://www.acmicpc.net/problem/23288
2. 내가 푼 방법
실수만 안 하면 금방 풀리는 빡구현 문제이다.
우선 서/북/동/남 순서로 방향을 설정했는데, 시계 방향 회전은 (dir + 1) % 4, 반시계 방향 회전은 (dir + 3) % 4, 반대 방향은 (dir + 2) % 4를 작성하여 코드를 간결하게 해주었다.
주사위를 굴리는 기능인 roll() 함수, 점수를 획득하는 기능인 getScore() 함수, 다음 방향을 계산하는 calculateDir() 함수로 구분했으며, 점수 획득하는 기능에서 BFS 알고리즘을 이용하는 것 외에는 인덱스랑 이동 위치만 실수하지 않으면 된다.
public static void solution() {
while (K-- > 0) {
roll();
getScore();
calculateDir();
}
}
public static void calculateDir() {
int A = dice[3][1];
int B = arr[sx][sy];
if (A > B) {
dir = (dir + 1) % 4;
}
else if (A < B) {
dir = (dir + 3) % 4;
}
}
public static void getScore() {
Queue<int[]> queue = new ArrayDeque<>();
boolean[][] visit = new boolean[N][M];
int cnt = 1;
visit[sx][sy] = true;
queue.add(new int[]{sx, sy});
while (!queue.isEmpty()) {
int[] q = queue.poll();
int x = q[0];
int y = q[1];
for (int d = 0; d < dx.length; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
if (visit[nx][ny] || arr[nx][ny] != arr[sx][sy]) continue;
cnt++;
visit[nx][ny] = true;
queue.add(new int[]{nx, ny});
}
}
result += (cnt * arr[sx][sy]);
}
public static void roll() {
int nx = sx + dx[dir];
int ny = sy + dy[dir];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) {
dir = (dir + 2) % 4;
nx = sx + dx[dir];
ny = sy + dy[dir];
}
sx = nx;
sy = ny;
rollDice();
}
public static void rollDice() {
if (dir == 0) {
int tmp = dice[1][1];
dice[1][1] = dice[1][2];
dice[1][2] = dice[3][1];
dice[3][1] = dice[1][0];
dice[1][0] = tmp;
}
else if (dir == 1) {
int tmp = dice[0][1];
dice[0][1] = dice[1][1];
dice[1][1] = dice[2][1];
dice[2][1] = dice[3][1];
dice[3][1] = tmp;
}
else if (dir == 2) {
int tmp = dice[1][1];
dice[1][1] = dice[1][0];
dice[1][0] = dice[3][1];
dice[3][1] = dice[1][2];
dice[1][2] = tmp;
}
else {
int tmp = dice[3][1];
dice[3][1] = dice[2][1];
dice[2][1] = dice[1][1];
dice[1][1] = dice[0][1];
dice[0][1] = tmp;
}
}
3. 자바 코드
깃허브 풀이 주소 : https://github.com/geujeog/BOJ/blob/main/B23288.java
import java.util.*;
import java.io.*;
class Main {
static int[] dx = {0, -1, 0, 1};
static int[] dy = {-1, 0, 1, 0};
static int N, M, K;
static int[][] arr;
static int sx, sy, dir;
static int[][] dice;
static int result;
public static void main (String[] args) throws IOException {
input();
solution();
output();
}
public static void solution() {
while (K-- > 0) {
roll();
getScore();
calculateDir();
}
}
public static void calculateDir() {
int A = dice[3][1];
int B = arr[sx][sy];
if (A > B) {
dir = (dir + 1) % 4;
}
else if (A < B) {
dir = (dir + 3) % 4;
}
}
public static void getScore() {
Queue<int[]> queue = new ArrayDeque<>();
boolean[][] visit = new boolean[N][M];
int cnt = 1;
visit[sx][sy] = true;
queue.add(new int[]{sx, sy});
while (!queue.isEmpty()) {
int[] q = queue.poll();
int x = q[0];
int y = q[1];
for (int d = 0; d < dx.length; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
if (visit[nx][ny] || arr[nx][ny] != arr[sx][sy]) continue;
cnt++;
visit[nx][ny] = true;
queue.add(new int[]{nx, ny});
}
}
result += (cnt * arr[sx][sy]);
}
public static void roll() {
int nx = sx + dx[dir];
int ny = sy + dy[dir];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) {
dir = (dir + 2) % 4;
nx = sx + dx[dir];
ny = sy + dy[dir];
}
sx = nx;
sy = ny;
rollDice();
}
public static void rollDice() {
if (dir == 0) {
int tmp = dice[1][1];
dice[1][1] = dice[1][2];
dice[1][2] = dice[3][1];
dice[3][1] = dice[1][0];
dice[1][0] = tmp;
}
else if (dir == 1) {
int tmp = dice[0][1];
dice[0][1] = dice[1][1];
dice[1][1] = dice[2][1];
dice[2][1] = dice[3][1];
dice[3][1] = tmp;
}
else if (dir == 2) {
int tmp = dice[1][1];
dice[1][1] = dice[1][0];
dice[1][0] = dice[3][1];
dice[3][1] = dice[1][2];
dice[1][2] = tmp;
}
else {
int tmp = dice[3][1];
dice[3][1] = dice[2][1];
dice[2][1] = dice[1][1];
dice[1][1] = dice[0][1];
dice[0][1] = tmp;
}
}
public static void output() throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write(result+"");
bw.flush();
bw.close();
}
public static void input() 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());
K = Integer.parseInt(st.nextToken());
arr = new int[N][M];
sx = sy = 0;
dir = 2;
dice = new int[4][3];
dice[1][1] = 1;
dice[0][1] = 2;
dice[1][0] = 4;
dice[1][2] = 3;
dice[2][1] = 5;
dice[3][1] = 6;
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
br.close();
}
}
4. 결과 및 회고
이번 문제는 한 번에 실수 없이 풀었다. 풀고 나니 주사위를 이동시키는 부분을 너무 하드코딩했나 싶은데,, 코테 풀 땐 저게 직관적이어서 저렇게 풀 거 같단 말이지
'문제풀이 > 백준' 카테고리의 다른 글
[JAVA] BOJ 백준 16930번 - 달리기 (0) | 2024.02.13 |
---|---|
[JAVA] BOJ 백준 2186번 - 문자판 (1) | 2024.02.13 |
[JAVA] BOJ 백준 16964번 - DFS 스페셜 저지 (4) | 2024.01.31 |
[JAVA] BOJ 백준 16437번 - 양 구출 작전 (1) | 2024.01.31 |
[JAVA] BOJ 백준 1938번 - 통나무 옮기기 (1) | 2024.01.24 |
댓글