https://www.acmicpc.net/problem/2178
N×M크기의 배열로 표현되는 미로가 있다.
1 0 1 1 1 1
1 0 1 0 1 0
1 0 1 0 1 1
1 1 1 0 1 1
미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.
위의 예에서는 15칸을 지나야 (N, M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.
입력
첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.
출력
첫째 줄에 지나야 하는 최소의 칸 수를 출력한다. 항상 도착위치로 이동할 수 있는 경우만 입력으로 주어진다.
package silver1;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class B2178 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] map = new int[N][M];
for (int i = 0; i < N; i++) { // map 입력
String str = br.readLine();
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(Character.toString(str.charAt(j)));
}
} // map 입력 끝
// map탐색 시작
int[] dr = { 1, -1, 0, 0 }; // 인접블록탐색용
int[] dc = { 0, 0, 1, -1 }; // 인접블록탐색용
int ans = 0; // 정답 출력용
Queue<int[]> q = new LinkedList<>(); // 탐색용 queue. BFS
boolean[][] visited = new boolean[N][M]; // 탐색했는지 검사
int[] startPoint = { 0, 0, 1 }; //탐색 시작지점과 건넌 블록수
q.add(startPoint); //시작지점 큐에 넣고 시작
/*탐색 찐 시작*/
while (!q.isEmpty()) {
int[] coor = q.poll(); // 좌표와 탐색을 몇번했는지 들어있는 변수
int r = coor[0]; // 현재 행 좌표
int c = coor[1]; // 현재 열 좌표
int block = coor[2]; // 현재 블록 탐색 개수
if (r == N - 1 && c == M-1) { //N, M에 도달했는지 검사
ans = block; //도달했으니 정답은 현재 블록 탐색 개수
// //for debugging
// System.out.println("N, M도달!!: "+r+" "+c);
break;
}
// //for debugging
// System.out.println("======현재 r: "+r+" 현재 c: "+c+" 현재 block: "+block+"======");
for (int n = 0; n < 4; n++) {
int nr = r + dr[n]; // 다음 행 위치
int nc = c + dc[n]; // 다음 열 위치
if (0 <= nr && nr < N && 0 <= nc && nc < M) { // 다음 블록이 범위 내
if (map[nr][nc]==1 && !visited[nr][nc]) { // 다음이 1이고 탐색 안했는지 검사
visited[nr][nc] = true;
int[] nowPoint = { nr, nc, block+1 };
q.add(nowPoint);
// //for debugging
// System.out.println("nr: "+nr+" nc: "+nc);
// //for debugging
// System.out.println("블록 찾음!");
// System.out.println(Arrays.toString(nowPoint));
} // 1 및 탐색 여부 검사 끝
} // 범위 검사 끝
} // 인접 블록 검사 끝
} // 탐색 끝
System.out.println(ans);
}
}
지금 백준 티어 실버2인데 어디선가 현재 티어 이상의 문제를 풀어야 한다고 들어서 실버 1에 있는 문제중에 참여자 수가 가장 많은 문제를 골랐다..
늘 풀던 BFS 최단경로 탐색 문제이다..
https://velog.io/@iamjinseo/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A82%EA%B2%8C%EC%9E%84-%EB%A7%B5-%EC%B5%9C%EB%8B%A8%EA%B1%B0%EB%A6%AC-python
https://velog.io/@iamjinseo/COS-Pro-6%EC%B0%A8-1%EA%B8%89-1%EB%B2%88-python
링크된 문제들과 많이 유사하다. 이번에는 그저 자바로 풀었을 뿐이다
자바로 바꿔서 그런지 파이썬보다 속도도 느리고 코드도 길다.....ㅠ흑