알고리즘/DFS & BFS

[백준]JAVA - 2412번: 암벽 등반

K.두부 2023. 4. 28. 15:00
반응형

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

 

2412번: 암벽 등반

어떤 암벽에 n(1 ≤ n ≤ 50,000)개의 홈이 파져 있다. 각각의 홈의 좌표는 (x, y)와 같이 표현되는데, |a - x| ≤ 2이고 |b - y| ≤ 2이면 (x, y)에서 (a, b)로 이동할 수 있다. 이와 같이 홈들을 이용하여 이동

www.acmicpc.net

🔶 풀이

BFS로 충분히 해결할 수 있는 문제.

 

(0, 0)에서 시작해서 (x, T)까지 올라가면 된다.

우선 입력값을 y값을 기준으로 배열을 만들어서 입력해줬다.

rock = new ArrayList[200001]; // T의 최대값: 2,000,000
for (int i=0; i<200001; i++) {
rock[i] = new ArrayList<>();
}

배열의 크기는 T의 최대값인 2,000,000에서 +1을 해준 값 2000001로 설정해줬다.

 

현재 위치(0, 0)를 queue에 입력해주고 BFS 탐색을 진행하면 된다.

현재 위치에서 ±2 까지 한 번에 이동할 수 있다고 했으니까 Queue에서 하나의 값을 꺼내면 현재 위치에서 x, y좌표 ±2의 범위를 모두 탐색해준 후에 이동 횟수(ans)를 늘려줘야한다.

 

ans: 현재 이동 횟수

q: 현재 위치

rock: 암벽에 박힌 홈

 

<최종코드>

import java.io.*;
import java.util.*;
public class Main {
static int N, T;
static ArrayList<Integer>[] rock;
public static class Pos {
int x, y;
public Pos(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 암벽에 박힌 홈 개수
T = Integer.parseInt(st.nextToken()); // 정상 위치 (y)
rock = new ArrayList[200001]; // T의 최대값: 2,000,000
for (int i=0; i<200001; i++) {
rock[i] = new ArrayList<>();
}
for (int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
rock[y].add(x);
}
// ★ 높이에 따른 x값 오름차순 정렬
for (int i=0; i<200001; i++) {
Collections.sort(rock[i]);
}
System.out.println(bfs());
}
public static int bfs() {
Queue<Pos> q = new LinkedList<>();
q.add(new Pos(0, 0));
int ans = 0;
while (!q.isEmpty()) {
int size = q.size();
for (int i=0; i<size; i++) {
Pos now = q.poll();
if (now.y == T) {
return ans;
}
for (int y=now.y-2; y<=now.y+2; y++) {
if (y < 0 || y >= 200001) continue;
for (int x=0; x<rock[y].size(); x++) {
if (now.x + 2 < rock[y].get(x)) break; // 큰 값이 나오면 볼 필요 없음
else if (now.x - 2 > rock[y].get(x)) continue;
q.add(new Pos(rock[y].get(x), y));
rock[y].remove(x); // 암벽 제거
x--; // remove를 하면 인덱스값이 작아지기때문에 -1
}
}
}
ans++;
}
return -1;
}
}

 

반응형