Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit da28815

Browse files
committed
고다혜: [BOJ] 1938 통나무 옮기기_240121
1 parent a0504e3 commit da28815

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

‎BOJ/1000-5000번/DH_1938.java‎

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 통나무 옮기기
6+
* 4 ≤ N ≤ 50
7+
*/
8+
9+
public class DH_1938 {
10+
static final boolean VERTICAL = true; // VERTICAL: 수직선, HORIZONTAL: 수평선
11+
static final int VERTICAL_IDX = 0, HORIZONTAL_IDX = 1;
12+
13+
static class Tree {
14+
int r, c;
15+
boolean isVertical;
16+
17+
public Tree(int r, int c, boolean isVertical) {
18+
this.r = r;
19+
this.c = c;
20+
this.isVertical = isVertical;
21+
}
22+
}
23+
24+
static class Node {
25+
Tree t;
26+
int depth;
27+
public Node(Tree t, int depth) {
28+
this.t = t;
29+
this.depth = depth;
30+
}
31+
}
32+
33+
static Tree start, end;
34+
static int N;
35+
static char[][] map;
36+
public static void main(String[] args) throws Exception {
37+
// System.setIn(new FileInputStream("./input/BOJ1938.txt"));
38+
39+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
40+
N = Integer.parseInt(br.readLine());
41+
42+
map = new char[N][N];
43+
44+
for(int r = 0; r < N; r++) {
45+
String s = br.readLine();
46+
map[r] = s.toCharArray();
47+
}
48+
49+
// 시작점과 끝 점 찾기
50+
findTree(map);
51+
52+
System.out.println(bfs());
53+
}
54+
55+
static int bfs() {
56+
Queue<Node> q = new ArrayDeque<Node>();
57+
58+
boolean[][][] v = new boolean[2][N][N];
59+
60+
// 세로로 이어져 있다면 0번 인덱스, 가로로 이어져 있다면 1번 인덱스
61+
q.add(new Node(start, 0));
62+
v[start.isVertical ? 0 : 1][start.r][start.c] = true;
63+
64+
while(!q.isEmpty()) {
65+
Node current = q.poll();
66+
67+
// 수직나무이면 0, 수평나무이면 1
68+
int currentIdx = current.t.isVertical ? 0 : 1;
69+
70+
if(current.t.r == end.r && current.t.c == end.c && current.t.isVertical == end.isVertical) {
71+
return current.depth;
72+
}
73+
74+
// 상, 하, 좌, 우로 이동
75+
for(int d = 0; d < 4; d++) {
76+
int nr = current.t.r + dr[d];
77+
int nc = current.t.c + dc[d];
78+
79+
if(!check(nr, nc) ||
80+
!canPositTree(nr, nc, current.t.isVertical) ||
81+
v[currentIdx][nr][nc] ||
82+
map[nr][nc] == '1') continue;
83+
84+
q.add(new Node(new Tree(nr, nc, current.t.isVertical), current.depth + 1));
85+
v[currentIdx][nr][nc] = true;
86+
}
87+
88+
// 90도 회전
89+
if(v[1 ^ currentIdx][current.t.r][current.t.c] ||
90+
!canRotate(current.t.r, current.t.c)) continue;
91+
92+
q.add(new Node(new Tree(current.t.r, current.t.c, !current.t.isVertical), current.depth + 1));
93+
v[1 ^ currentIdx][current.t.r][current.t.c] = true;
94+
}
95+
96+
return 0;
97+
}
98+
99+
static boolean canRotate(int r, int c) {
100+
101+
// 90도 회전하는 과정에서 걸리는게 있는지 확인
102+
for(int sr = r - 1; sr < r + 2; sr++) {
103+
for(int sc = c - 1; sc < c + 2; sc++) {
104+
if(!check(sr, sc) || map[sr][sc] == '1') return false;
105+
}
106+
}
107+
108+
return true;
109+
}
110+
111+
// 센터 양 옆으로 세울 수 있는지 확인
112+
static boolean canPositTree(int r, int c, boolean isVertical) {
113+
int cr1 = isVertical ? r - 1: r, cc1 = isVertical ? c : c - 1;
114+
int cr2 = isVertical ? r + 1: r, cc2 = isVertical ? c : c + 1;
115+
116+
if(!check(cr1, cc1) || !check(cr2, cc2)) return false;
117+
if(map[cr1][cc1] == '1' || map[cr2][cc2] == '1') return false;
118+
return true;
119+
}
120+
121+
static int[] dr = {-1, 1, 0, 0}, dc = {0, 0, -1, 1};
122+
123+
124+
// 3개로 연속되어 있는 나무들 찾기
125+
// 시작점과 끝 점 모두 찾기
126+
static void findTree(char[][] map) {
127+
128+
for(int r = 0; r < N; r++) {
129+
for(int c = 0; c < N; c++) {
130+
131+
if(map[r][c] == 'B' && start == null) {
132+
for(int i = 0; i < 2; i++) {
133+
start = getFindTree(r, c, i, map, map[r][c]);
134+
if(start != null) break;
135+
}
136+
}
137+
138+
if(map[r][c] == 'E' && end == null) {
139+
for(int i = 0; i < 2; i++) {
140+
end = getFindTree(r, c, i, map, map[r][c]);
141+
if(end != null) break;
142+
}
143+
}
144+
}
145+
}
146+
}
147+
148+
static Tree getFindTree(int r, int c, int i, char[][] map, char ch) {
149+
150+
// i == 0 -> 세로
151+
// i == 1 -> 가로
152+
int cr1 = i == 0 ? r - 1: r, cc1 = i == 0 ? c : c - 1;
153+
int cr2 = i == 0 ? r + 1: r, cc2 = i == 0 ? c : c + 1;
154+
155+
if(!check(cr1, cc1) || !check(cr2, cc2)) return null;
156+
157+
if(map[cr1][cc1] != ch || map[cr2][cc2] != ch) return null;
158+
159+
// 세로
160+
if(i == 0)return new Tree(r, c, VERTICAL);
161+
return new Tree(r, c, !VERTICAL);
162+
}
163+
164+
static boolean check(int r, int c) {
165+
return r >= 0 && r < N && c >= 0 && c < N;
166+
}
167+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /