문제 >> [BOJ] 1938. 통나무 옮기기




저는 기본적으로 통나무의 위치를 가운데 좌표와 모양(세로/가로)의 정보로 파악했습니다.

  1. 출발 통나무와 도착 통나무의 위치를 저장.

  1. bfs로 진행

** 4차원의 visit 배열

  • 통나무 모양에 따라서

  • 5가지 행위에 대해서



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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
 
//BOJ :: 1938 통나무 옮기기     
public class Main1938_통나무옮기기2 {
    private static char[][] map;
    private static boolean[][][][] visit;
    private static int N;
    private static ArrayList<pair> nowLog;
    private static ArrayList<pair> destLog;
    private static log end;
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        nowLog = new ArrayList<>();
        destLog = new ArrayList<>();
 
        map = new char[N][N];
        visit = new boolean[5][2][N][N];
 
        for (int i = 0; i < N; i++) {
            String str = br.readLine();
            for (int j = 0; j < N; j++) {
                map[i][j] = str.charAt(j);
                if (map[i][j] == 'B')
                    nowLog.add(new pair(i, j));
                if (map[i][j] == 'E')
                    destLog.add(new pair(i, j));
 
            }
        } //// input
 
        Collections.sort(nowLog);
        Collections.sort(destLog);
        int type;
        if (nowLog.get(0).y == nowLog.get(1).y) type = 2else type = 1;
        log start = new log(nowLog.get(1).y, nowLog.get(1).x, type, 0);
 
        if (destLog.get(0).y == destLog.get(1).y) type = 2else type = 1;
        end = new log(destLog.get(1).y, destLog.get(1).x, type, 0);
        System.out.println(bfs(start));
    } // end of main
 
    static int[] dy = { -1100-1-111 };
    static int[] dx = { 00-11-11-11 }; // 상하좌우//대각선
 
    public static int bfs(log start) {
 
        Queue<log> q = new LinkedList<>();
        q.add(start);
        // visit[][start.type-1][start.y][start.x] = true;
        while (!q.isEmpty()) {
            log now = q.poll();
            int y = now.y;
            int x = now.x; // 통나무의 mid 정보
            int type = now.type;
            int cnt = now.cnt;
            // 종료조건 확인
            if (y == end.y && x == end.x && type == end.type) {
                return cnt;
            }
 
            for (int i = 0; i < 5; i++) {
                if (i == 4) { // 회전
                    boolean isPossible = true;
                    // 회전할 수 있는 범위 확인.
                    for (int chk = 0; chk < 8; chk++) {
                        int ny = y + dy[chk];
                        int nx = x + dx[chk];
                        if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || map[ny][nx] == '1') {
                            isPossible = false;
                            break;
                        }
                    }
                    if (!isPossible) continue;
                    int ntype;
                    if (type == 1) ntype = 2;
                    else ntype = 1;
                    if (!visit[i][type - 1][y][x]) {
                        q.add(new log(y, x, ntype, cnt + 1));
                        visit[i][type - 1][y][x] = true;
                    }
 
                } else if (i < 4) {// 상하좌우 이동
                    int ny = y + dy[i];
                    int nx = x + dx[i];
                    if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || map[ny][nx] == '1'
                            || visit[i][type - 1][ny][nx])
                        continue;
                    if (type == 1) { // |
                        int topY = ny - 1;
                        int bottomY = ny + 1;
                        if (topY < 0 || bottomY > N - 1 || map[topY][nx] == '1' || map[bottomY][nx] == '1'continue;
                    } else { // -
                        int leftX = nx - 1;
                        int rightX = nx + 1;
                        if (leftX < 0 || rightX > N - 1 || map[ny][leftX] == '1' || map[ny][rightX] == '1'continue;
                    }
                    visit[i][type - 1][ny][nx] = true;
                    q.add(new log(ny, nx, type, cnt + 1));
                }
            }
        }
        return 0;
    }
 
    static class log {
        int y;
        int x;
        int type; // 1 : | // 2: -
        int cnt;
        public log(int y, int x, int type, int cnt) {
            super();
            this.y = y;
            this.x = x;
            this.type = type;
            this.cnt = cnt;
        }
    }
 
    static class pair implements Comparable<pair> {
        int y;
        int x;
        public pair(int y, int x) {
            super();
            this.y = y;
            this.x = x;
        }
        @Override
        public int compareTo(pair o) {
            if (o.x == this.x)
                return o.x - this.x;
            else if (o.y == this.y) {
                return o.y - this.y;
            }
            return -1;
        }
    }
}
cs


'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09
[SWEA] 2383. 점심식사 시간  (5) 2019.04.04
[SWEA] 1949. 등산로 조성  (0) 2019.04.01
[BOJ] 1805. 나무자르기  (4) 2019.03.22

+ Recent posts