728x90
1261 - 알고스팟
https://www.acmicpc.net/problem/1261

문제
미로는 N*M 크기이며 총 1*1 크기의 방으로 이뤄져 있음
/ 빈 방(0) or 벽(1)으로 이뤄져 있고 빈 방은 자유롭게 다닐 수 있지만, 벽은 부수지 않으면 이동할 수 없음
어떤 방에서 이동할 수 있는 방은 상하좌우로 인접한 빈 방
ex. (x, y) -> (x+1, y), (x, y+1), (x-1, y), (x, y-1)
입력
첫째 줄: 가로 M, 세로 N (1 <= N, M <= 100)
다음 N개 줄: 숫자 0, 1
(1, 1)과 (N, M)은 항상 뚫려 있음
출력: 현재 (1, 1)에서 (N, M)으로 이동하려면 벽을 최소 몇 개 부수어야 하는지
풀이
0-1 BFS
가중치가 0/1만 있는 그래프에서 최단거리 구하는 BFS
- 가중치 0 -> `Deque`의 앞에 넣음
- 0 비용 이동: 우선적으로 탐색
- 가중치 1 -> `Deque`의 뒤에 넣음
- 1 비용 이동: 나중에 탐색
static int bfs() {
Deque<int[]> dq = new ArrayDeque<>();
dq.offer(new int[]{0, 0});
dist[0][0] = 0;
while (!dq.isEmpty()) {
int[] cur = dq.poll();
int x = cur[0];
int y = cur[1];
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
int weight = map[nx][ny];
if (dist[nx][ny] > dist[x][y] + weight) {
dist[nx][ny] = dist[x][y] + weight;
if (weight == 0) dq.addFirst(new int[]{nx, ny});
else dq.addLast(new int[]{nx, ny});
}
}
}
return dist[N - 1][M - 1];
}
참고 - 상태를 변화시키는 BFS 문제
1을 0으로 바꿀 수 있음
ex. 최대 벽을 K번 부수기 (백준 2206)
-> 비용 누적 X 가장 먼저 도착한 것이 정답 => BFS
But, 비용 누적해서 최소 비용 구하기 -> 최단 거리 문제 => 0-1 BFS
코드
import java.io.*;
import java.util.*;
// 알고스팟
public class boj_1261 {
static int M, N;
static int[][] map, dist;
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
static final int INF = Integer.MAX_VALUE;
static int bfs() {
Deque<int[]> dq = new ArrayDeque<>();
dq.offer(new int[]{0, 0});
dist[0][0] = 0;
while (!dq.isEmpty()) {
int[] cur = dq.poll();
int x = cur[0];
int y = cur[1];
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
int weight = map[nx][ny];
if (dist[nx][ny] > dist[x][y] + weight) {
dist[nx][ny] = dist[x][y] + weight;
if (weight == 0) dq.addFirst(new int[]{nx, ny});
else dq.addLast(new int[]{nx, ny});
}
}
}
return dist[N - 1][M - 1];
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
dist = new int[N][M];
for (int i = 0; i < N; i++) {
Arrays.fill(dist[i], INF);
}
map = new int[N][M];
for (int i = 0; i < N; i++) {
String line = br.readLine();
for (int j = 0; j < M; j++) {
map[i][j] = line.charAt(j) - '0';
}
}
System.out.println(bfs());
}
}728x90
반응형
'✏️ > BOJ' 카테고리의 다른 글
| [BOJ/Dijkstra] 백준 4485 - 녹색 옷을 입은 애가 젤다지? (Java) (0) | 2025.11.20 |
|---|---|
| [BOJ/Dijkstra] 백준 1916 - 최소비용 구하기 / 11779 - 최소비용 구하기 2 (Java) (0) | 2025.11.19 |
| [BOJ/Dijkstra] 백준 1238 - 파티 (Java) (0) | 2025.11.17 |
| [BOJ/DP] 백준 10942 - 팰린드롬? (Java) (0) | 2025.11.17 |
| [BOJ/Back-Tracking] 백준 1987 - 알파벳 (Java) (0) | 2025.11.17 |