티스토리 뷰
https://www.acmicpc.net/problem/2178
문제
N×M크기의 배열로 표현되는 미로가 있다.
101111
101010
101011
111011
미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.
위의 예에서는 15칸을 지나야 (N, M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.
(조건)
첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은
붙어서 입력으로 주어진다.
(출력)
첫째 줄에 지나야 하는 최소의 칸 수를 출력한다. 항상 도착위치로 이동할 수 있는 경우만 입력으로 주어진다.
문제분석하기
데이터의 크기가 100 이하이므로, 시간제한의 경우 별도로 고민할 필요가 없다
문제의 요구사항은 지나하야하는 칸 수의 최솟값을 찾는 것이므로, BFS를 사용해 최초로 도달했을때의 경우의 수를 구하면 된다
BFS를 이용하여 풀이를 진행
풀이과정)
1. 상하좌우의 배열을 이용하여 체크하는 방식
2. 방문했던 곳은 따로 저장하여, 체크 진행
3. 상하좌우를 체크했을때 방문하지 않았다면 방문 체크 후 큐 삽입 (큐가 빌때까지 진행)
슈도코드
dx, dy (상하좌우를 체크하기위한 정의 변수)
arr(2차원 행렬)
N(행) M(열)
visited(방문 체크)
arr, visited 초기화
BFS(0,0) // 0,0부터 진행
BFS{
큐 자료구조에 시작 노드 삽입
visited 현재 노드 방문 기록
while(큐가 빌때까지){
큐에서 노드 가져오기
for(상하좌우 탐색){
if(유효한좌표){
if(방문하지 않은 노드){
visited = 방문기록
큐에 데이터 삽입
arr 배열에 현재 노드의 depth+1로 업데이트하기 // depth 기록
}
}
}
}
}
구현
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.util.Queue;
public class App { // 상 하 좌 우
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
static boolean[][] visited;
static int[][] arr;
static int N, M;
public static void main(String[] args) throws Exception {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[N][M];
visited = new boolean[N][M];
for(int i =0; i< N; i++){
st = new StringTokenizer(bf.readLine());
String line = st.nextToken();
for(int j =0; j < M; j++){
arr[i][j] = Integer.parseInt(line.substring(j, j+1));
}
}
BFS(0,0);
System.out.println(arr[N-1][M-1]);
}
public static void BFS(int i, int j){
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[] {i,j});
while(!queue.isEmpty()){
int now[] = queue.poll();
visited[i][j] = true;
for(int k = 0; k<4; k++){
int x = now[0] + dx[k];
int y = now[1] + dy[k];
if( x >= 0 && y>=0 && x<N && y<M){
if(arr[x][y] != 0 && !visited[x][y]){
visited[x][y] = true;
arr[x][y] = arr[now[0]][now[1]] +1; // depth 저장
queue.add(new int[] {x,y});
}
}
}
}
}
}
'책 > DoIt 알고리즘 코딩테스트' 카테고리의 다른 글
[이진탐색] 백준 1920번 (0) | 2024.11.21 |
---|---|
[BFS] 백준 1167번 (트리의 지름) (0) | 2024.11.20 |
[BFS + DFS] 백준 1260번 (0) | 2024.11.18 |
[DFS] 백준 13023번 (0) | 2024.11.17 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 우선순위 큐
- BFS
- JDBC
- 오블완
- DFS
- Thymeleaf
- 코딩테스트
- 정렬
- HTML5
- 알고리즘
- db
- Java
- 깊이우선탐색
- 이진탐색
- 버블정렬
- 기술면접
- bean
- stack
- 검증
- 타입변환
- JSON
- Spring
- SQL
- 포트폴리오
- 게시판 프로젝트
- 예외처리
- 클래스
- 백준
- 티스토리챌린지
- 게시판
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함