본문 바로가기
알고리즘/백준

[BOJ 14497] 주난의 난(c++)

by umdoyun 2026. 3. 27.
728x90

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

문제 개요

N×M 크기의 교실에서 주난이가 상하좌우로 파동을 퍼뜨려 범인을 잡는 문제입니다. 파동은 장애물(친구들)을 만날 때까지 계속 퍼져나가며, 한 번의 점프가 한 겹의 친구들을 쓰러뜨립니다. 주난이의 위치에서 범인의 위치까지 도달하는 데 필요한 최소 점프 횟수를 구해야 합니다.

  • (1 ≤ N, M ≤ 300)

문제 풀이

이 문제는 다익스트라(우선순위 큐 BFS) 로 해결하였습니다.

핵심 아이디어는 다음과 같습니다.

  • 파동이 퍼져나갈 때, 빈 공간(0)을 지나는 것은 비용이 0이고, 친구(1 또는 #)를 만나면 비용이 1(점프 1회) 발생합니다.
  • 즉, 이동 비용이 0 또는 1인 최단 경로 문제이므로 우선순위 큐(최소 힙)를 사용하는 다익스트라로 해결할 수 있습니다.
  • 출발점에서 상하좌우로 탐색하며, 해당 칸이 빈 칸이면 현재 점프 횟수 유지, 친구가 있는 칸이면 점프 횟수를 1 증가시켜 큐에 삽입합니다.
  • 범인(#)의 위치에 도달했을 때의 점프 횟수를 출력합니다.

코드

#include <iostream>
#include <queue>
using namespace std;

class node {
public:
	int x, y, cnt;
	bool operator < (const node& other) const {
		return cnt > other.cnt;
	}
};

int n, m;
char coord[301][301];
bool visit[301][301];

int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };

int bfs(int sx, int sy, int ex, int ey) {
	priority_queue<node> pq;
	pq.push({ sx, sy, 0 });
	visit[sx][sy] = true;
	while (!pq.empty()) {
		int x = pq.top().x;
		int y = pq.top().y;
		int cnt = pq.top().cnt;
		if (x == ex && y == ey) return cnt;
		pq.pop();
		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if (nx < 1 || ny < 1 || nx > n || ny > m || visit[nx][ny]) continue;
			visit[nx][ny] = true;
			int ncnt = cnt;
			if (coord[nx][ny] != '0') ncnt++;
			pq.push({ nx, ny, ncnt});
		}
	}
	return -1;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int sx, sy, ex, ey;
	cin >> n >> m >> sx >> sy >> ex >> ey;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> coord[i][j];
		}
	}
	int res = bfs(sx, sy, ex, ey);
	cout << res << '\n';
	return 0;
}

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ 15835] Explorace(c++)  (0) 2026.03.30
[BOJ 1477] 휴게소 세우기(c++)  (0) 2026.03.06
[BOJ 1744] 수 묶기 (c++)  (0) 2026.03.05
[BOJ 2109] 순회강연(c++)  (0) 2026.03.03
[BOJ1615] 교차개수세기(c++)  (1) 2026.02.11