알고리즘 문제 풀이/BOJ

[backjoon] 23288 주사위 굴리기 2 java

v 2022. 3. 29. 16:00

https://www.acmicpc.net/problem/23288

 

23288번: 주사위 굴리기 2

크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼

www.acmicpc.net

주사위 굴리기 1과 매우 유사한데 희한한 BFS가 추가되었다.

1. 주사위를 굴린다. 주사위를 굴릴 수가 없다면 반대 방향으로 굴린다.

2. 굴려진 위치와 그 주변을 탐색해서 숫자가 같은 것들의 갯수를 구한다.

문제 해독이 좀 어려웠다...

주사위는 1차원 배열을 이용해서 위치만 바꿔주는 방식으로 구현하였다.

주사위 굴리는 방법은 [backjoon]14499 주사위 굴리기 java을 참고.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import java.io.*;
import java.util.*;
 
class Main {
    static int[] dice = new int[] { 123456 };
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
 
        // << 초기화  >>
        int[][] map = new int[N][M];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                int cur = Integer.parseInt(st.nextToken());
                map[i][j] = cur;
            }
        }
        int[][] dirs = { { 01 }, { 10 }, { 0-1 }, { -10 } };
        int curD = 0;
        int[] cur = new int[] { 00 };
        int answer = 0;
        
        // << 주사위 굴려서 이동하기>>
        while (K-- > 0) {
            // 방향 정하기 -> 벽을 만났다면 반대편으로 이동하기 -> 주사위 위치 갱신하기
            int[] nextCur = { cur[0+ dirs[curD][0], cur[1+ dirs[curD][1] };
            if (nextCur[0< 0 || nextCur[1< 0 || nextCur[0>= N || nextCur[1>= M) {
                curD = (curD + 2) % 4;
                nextCur = new int[] { cur[0+ dirs[curD][0], cur[1+ dirs[curD][1] };
            }
            dice(curD);
            cur = nextCur;
            
            // 이동 방향 결정하기
            int A = dice[5];
            int B = map[cur[0]][cur[1]];
            if (A > B) {
                curD = (curD + 1) % 4;
            } else if (A < B) {
                curD = (curD + 3) % 4;
            }
 
            // BFS로 이동하기
            int C = 1;
            Queue<int[]> queue = new LinkedList<>();
            boolean[][] marked = new boolean[N][M];
            marked[cur[0]][cur[1]] = true;
            queue.add(cur);
            while (!queue.isEmpty()) {
                int[] now = queue.poll();
                for (int d = 0; d < 4; d++) {
                    int nextR = now[0+ dirs[d][0];
                    int nextC = now[1+ dirs[d][1];
                    if (nextR < 0 || nextC < 0 || nextR >= N || nextC >= M)
                        continue;
                    if (marked[nextR][nextC])
                        continue;
                    if (map[nextR][nextC] != B)
                        continue;
                    queue.add(new int[] { nextR, nextC });
                    marked[nextR][nextC] = true;
                    C++;
                }
            }
            answer += B * C;
        }
        System.out.println(answer);
    }
 
    static void dice(int dir) {
        int temp = 0;
        temp = 0;
        switch (dir) {
        case 0// ->
            temp = dice[0];
            dice[0= dice[3];
            dice[3= dice[5];
            dice[5= dice[2];
            dice[2= temp;
            break;
        case 1:// v4
            temp = dice[0];
            dice[0= dice[1];
            dice[1= dice[5];
            dice[5= dice[4];
            dice[4= temp;
            break;
        case 2:// <- 2
            temp = dice[0];
            dice[0= dice[2];
            dice[2= dice[5];
            dice[5= dice[3];
            dice[3= temp;
            break;
        case 3:// ^3
            temp = dice[0];
            dice[0= dice[4];
            dice[4= dice[5];
            dice[5= dice[1];
            dice[1= temp;
            break;
 
        default:
            break;
        }
    }
}
 
cs
반응형