Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 항해99
- 코딩테스트사이트추천
- 데이터베이스
- 알고리즘
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 운영체제
- 갭체크
- 파이썬
- 자바
- 웹
- 프로그래머스
- Java
- 코딩테스트준비
- 개발자루틴
- 티스토리챌린지
- til
- 플로이드-워셜
- C
- 프로그래밍 언어
- 자바스크립트
- 개발자취업
- 코드트리
- 99클럽
- 자료구조
- 인접 행렬
- 오블완
- 1일1코테
- 코딩테스트
- 코테공부
- 연결 리스트
Archives
- Today
- Total
와드의 블로그
2178번: 미로 탐색 본문
문제
N×M 크기의 배열로 표현되는 미로가 있습니다. 미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타냅니다. (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 문제입니다. 한 칸에서 다른 칸으로 이동할 때에는 서로 인접한 칸으로만 이동할 수 있습니다. (칸을 셀 때에는 시작 위치와 도착 위치도 포함합니다.)
- 입력: 첫째 줄에 두 정수 N, M (2 ≤ N, M ≤ 100)이 주어집니다. 다음 N개의 줄에는 M개의 정수로 미로가 주어집니다. 각각의 수들은 붙어서 입력으로 주어집니다.
- 출력: 첫째 줄에 지나야 하는 최소의 칸 수를 출력합니다.
링크: https://www.acmicpc.net/problem/2178
풀이
가중치가 동일한(모든 칸의 이동 거리가 1인) 2차원 격자에서 출발점으로부터 도착점까지의 최단 경로를 찾는 문제이므로, 너비 우선 탐색(BFS)을 사용하는 가장 대표적인 유형입니다.
- 상태 관리 클래스 및 큐 초기화: 좌표 (y, x)를 담기 위해 Node 클래스를 생성하고, BFS 탐색을 위한 큐(Queue)를 선언합니다. 시작점인 (0, 0)을 큐에 넣고 방문 처리를 합니다.
- 이동 거리 누적 배열 (visited): visited 배열을 단순한 boolean 타입의 방문 여부 체크용이 아닌 int 타입으로 선언합니다. 이를 통해 방문 여부(0이면 미방문, 0이 아니면 방문)를 확인함과 동시에, 시작점으로부터 해당 칸까지 이동하는 데 걸린 최소 칸 수를 누적하여 기록할 수 있습니다.
- 시작점의 거리를 1로 초기화합니다: visited[0][0] = 1;
- 다음 칸으로 이동할 때 이전 칸의 거리에서 1을 더해줍니다: visited[ny][nx] = visited[node.y][node.x] + 1;
- 상하좌우 탐색 (BFS): 큐에서 좌표를 하나씩 꺼내어 상하좌우 4방향을 탐색합니다.
- 미로의 범위를 벗어나지 않고 (ny >= 0 && nx >= 0 && ny < n && nx < m)
- 벽이 아니며 (a[ny][nx] != '0')
- 아직 방문하지 않은 칸 (visited[ny][nx] == 0) 위 조건을 모두 만족하는 칸만 큐에 추가하여 탐색을 이어나갑니다.
- 결과 출력: BFS 탐색이 모두 끝나면 목적지인 (N-1, M-1) 좌표의 visited 배열 값을 출력합니다. 도착점의 값이 곧 시작점부터 도착점까지의 최단 거리가 됩니다.
코드
import java.io.*;
import java.util.*;
public class Main {
// 상하좌우 탐색을 위한 델타 배열
static int[] dy = {-1, 0, 1, 0};
static int[] dx = {0, 1, 0, -1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
// 미로 배열 입력 처리
char[][] a = new char[n][m];
for (int i = 0; i < n; i++) {
a[i] = br.readLine().toCharArray();
}
// 방문 여부 및 누적 거리를 저장할 배열
int[][] visited = new int[n][m];
Queue<Node> q = new LinkedList<>();
// 시작점 (0, 0) 초기화
q.add(new Node(0, 0));
visited[0][0] = 1; // 시작 위치도 칸 수에 포함하므로 1부터 시작
// 너비 우선 탐색 (BFS) 진행
while (!q.isEmpty()) {
Node node = q.poll();
// 상하좌우 4방향 탐색
for (int i = 0; i < 4; i++) {
int ny = node.y + dy[i];
int nx = node.x + dx[i];
// 1. 미로 범위를 벗어나면 무시
if (ny < 0 || nx < 0 || ny >= n || nx >= m)
continue;
// 2. 벽('0')이거나 이미 방문한 칸이면 무시
if (a[ny][nx] == '0' || visited[ny][nx] != 0)
continue;
// 이동할 수 있는 칸이면 큐에 추가하고, 이전 칸의 이동 거리 + 1 기록
q.add(new Node(ny, nx));
visited[ny][nx] = visited[node.y][node.x] + 1;
}
}
// 도착점(우측 하단 끝)에 기록된 최소 이동 칸 수 출력
bw.write(visited[n - 1][m - 1] + "");
bw.flush();
bw.close();
br.close();
}
// 좌표 정보를 큐에 담기 위한 내부 클래스
static class Node {
int y, x;
public Node(int y, int x) {
this.y = y;
this.x = x;
}
}
}
알고리즘 분류
그래프 탐색 (Graph Traversal), 너비 우선 탐색 (BFS)
'PS > B.O.J' 카테고리의 다른 글
| 2468번: 안전 영역 (0) | 2026.03.21 |
|---|---|
| 1012번: 유기농 배추 (0) | 2026.03.21 |
| 4375번: 1 (0) | 2026.03.20 |
| 1629번: 곱셈 (0) | 2026.03.20 |
| 3986번: 좋은 단어 (0) | 2026.03.20 |