Skip to content

Commit 31d1ad5

Browse files
authored
[20260204] BOJ / G4 / 암벽 등반 / 이인희
1 parent d8bd7b0 commit 31d1ad5

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
```java
2+
import java.io.BufferedReader;
3+
import java.io.IOException;
4+
import java.io.InputStreamReader;
5+
import java.awt.Point;
6+
import java.util.ArrayDeque;
7+
import java.util.ArrayList;
8+
import java.util.Arrays;
9+
import java.util.Deque;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
14+
public class Main {
15+
private static int T = 0;
16+
private static int N = 0;
17+
/*
18+
19+
*/
20+
private static List<Point> Points;
21+
private static Map<Integer, int[]> DpPointsAtX;
22+
private static boolean[] Visited;
23+
public static void main(String[] args) throws IOException {
24+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
25+
Points = new ArrayList<Point>();
26+
DpPointsAtX = new HashMap<>();
27+
28+
String[] tokens = br.readLine().split(" ");
29+
// 0. bfs 큐에 시작지점 추가, 포인트 정렬
30+
N = Integer.parseInt(tokens[0]);
31+
T = Integer.parseInt(tokens[1]);
32+
Visited = new boolean[N];
33+
int n = N;
34+
while(n-->0){
35+
tokens = br.readLine().split(" ");
36+
Points.add(new Point(Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1])));
37+
}
38+
Points.sort((o1, o2) -> o1.x - o2.x);
39+
Deque<long[]> q = new ArrayDeque<>( );
40+
q.offer(new long[]{0, 0, 0});
41+
long answer = 0;
42+
while(!q.isEmpty()){
43+
// 1. bfs시작
44+
long[] qItem = q.poll();
45+
long x = qItem[0]; long y = qItem[1]; long step = qItem[2];
46+
if(y == T){
47+
answer = step;
48+
break;
49+
}
50+
int[] idxBoundOfPointsAtX = getPointsAtX((int) x);
51+
for(int i = idxBoundOfPointsAtX[0]; i < idxBoundOfPointsAtX[1]; i++){
52+
int ny = Points.get(i).y;
53+
if(Math.abs(y - ny)>2){
54+
continue;
55+
}
56+
if(Visited[i]) continue;
57+
q.offer(new long[]{Points.get(i).x, ny, step+1});
58+
Visited[i] = true;
59+
}
60+
}
61+
// for(Map.Entry<Integer, int[]> entry : DpPointsAtX.entrySet()){
62+
// System.out.println(entry.getKey() + " : " + Arrays.toString(entry.getValue()));
63+
// }
64+
System.out.println((answer != 0)? answer : -1);
65+
// 2-0. dpPointsAtX에 있는지 확인
66+
// 2. 현재 시작지점에서 x 차2인것들의 인덱스 범위 추론 -> pointsAtX
67+
// 3. pointsAtX으로 pointsAtXY 를 구함(O(len(pointsAtX)))
68+
// 4. dpPointsAtX 에 pointsAtXY를 저장
69+
70+
br.close();
71+
}
72+
73+
private static int[] getPointsAtX(int x) {
74+
int[] idxsPointsAtX = DpPointsAtX.get(x);
75+
if(idxsPointsAtX == null){
76+
//이분탐색으로 구해야함
77+
int idxOfLowerBound = getLowerBound(x-2);
78+
int idxOfUppderBound = getUppderBound(x+2);
79+
//삽입
80+
DpPointsAtX.putIfAbsent(x, new int[]{idxOfLowerBound, idxOfUppderBound});
81+
idxsPointsAtX = DpPointsAtX.get(x);
82+
}
83+
return idxsPointsAtX;
84+
}
85+
86+
private static int getUppderBound(int v) {
87+
int l = -1; int r = Points.size();
88+
while(l + 1 < r){
89+
int mid = (l + r) / 2;
90+
if(!(Points.get(mid).x > v)) {
91+
l = mid;
92+
}else{
93+
r = mid;
94+
}
95+
}
96+
return r;
97+
}
98+
99+
private static int getLowerBound(int v) {
100+
int l = -1; int r = Points.size();
101+
while(l + 1 < r){
102+
int mid = (l + r) / 2;
103+
if(!(Points.get(mid).x >= v)) {
104+
l = mid;
105+
}else{
106+
r = mid;
107+
}
108+
}
109+
return r;
110+
}
111+
112+
}
113+
```

0 commit comments

Comments
 (0)