일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자고 싶다
- 우유가 옆으로 넘어지면 아야
- SSAFY 화이팅
- 자료구조
- DFS
- have a nice day
- 우유아야
- SSAFY 10기 화이팅
- 텐션 업 10기 화이팅
- 우유가옆으로넘어지면아야
- 텐션 업 10기!
- SeongSeobDang
- BFS
- 코로나 싫어요
- Have a good day :)
- SSAFY IM/A
- I am Korean
- 모르고리즘
- Hamming weight
- LeetCode #릿코드 #좋은 하루 되세요 #Have a nice day
- 수학
- Java 환경 설정
- 아자아자 화이팅
- HAVE A GOOD DAY
- SSAFY 테스트
- DP
- amazon
- 네트워크
- Have a nice day.
- Today
- Total
Hope Everyone Is Happy
[실버1] 2178. 미로 탐색 (Java) 본문
https://www.acmicpc.net/problem/2178
2178번: 미로 탐색
첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.
www.acmicpc.net
BFS 문제를 드디어 도전 해봅니다!!!
※ 문제를 요약하면 아래와 같습니다.
▶ N x M 크기의 미로가 배열 형태로 주어짐
▶ 배열의 원소들(미로)은 0과 1로 이루어져 있으며 상,하,좌,우 방향으로 1로만 이동이 가능.
▶ (1,1) 부터 (N,M) 까지 가는 경로의 최단 길이 탐색. (시작 칸과 끝 칸 포함)
▶ 위의 조건에 따라서 입력은 맨 첫줄에 N, M 을 입력 받고, 그 다음 라인부터 N x M 크기만큼 미로의 값들을 입력.
▶ (1,1) 부터 (N, M) 까지 가는 최단 경로 수 출력
◈ Input - 1
4 6
101111
101010
101011
111011
◈ Output - 1
15
◈ Input - 2 ( 드럽다 진짜.. )
2 25
1011101110111011101110111
1110111011101110111011101
◈ Output - 2
38
◎ 코드 작성 전, 아래와 같이 솔루션을 정리하였습니다.
▶ 미로 값 저장 배열은 boolean 형 배열로 선언 (원소가 0과 1로 구성)
▶ 탐색 여부 체크 배열 또한 boolean 형 배열로 선언
▶ 북,동,남,서 순서로 탐색 방향 설정
▶ Row, Col 의 좌표 및 지나간 경로의 갯수를 멤버변수로 설정한 MazeInform 클래스 선언
▶ BFS를 위한 큐 자료형 선언. ( 큐의 FIFO 성질을 활용, 1일 경우 In, 0일 경우 Out )
▶탐색 시 인덱스 범위 밖이거나 이미 탐색한 인덱스의 경우 Out
▶ 마지막 방 번호 도달 시 최소값 비교를 하여 min 변수에 결과 저장.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class MazeInform {
int nRow;
int nCol;
int nCount;
public MazeInform(int nRow, int nCol, int nCount) {
this.nRow = nRow;
this.nCol = nCol;
this.nCount = nCount;
}
}
public class Main {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int nMin = 9999999;
BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bReader.readLine());
int nRows = Integer.parseInt(st.nextToken());
int nCols = Integer.parseInt(st.nextToken());
// 미로 값 저장 배열, 탐색 여부 저장 배열.
boolean[][] barrMaze = new boolean[nRows][nCols];
boolean[][] bIsSearched = new boolean[nRows][nCols];
// 미로 값 저장.
for(int i = 0; i < nRows; i++) {
String strTemp = bReader.readLine();
for(int j = 0; j < nCols; j++) {
if(strTemp.charAt(j) == '1')
barrMaze[i][j] = true;
else
barrMaze[i][j] = false;
}
}
// 북, 동, 남, 서
int[] dr = {1, 0, -1, 0};
int[] dc = {0, 1, 0, -1};
// BFS를 위한 큐 + (0,0)은 반드시 1 (문제에서의 (1,1))
Queue<MazeInform> qBuffer = new LinkedList<>();
bIsSearched[0][0] = true;
qBuffer.add(new MazeInform(0, 0, 1));
// BFS
while(!qBuffer.isEmpty()) {
MazeInform mazeTemp = qBuffer.poll();
for(int k = 0; k < dr.length; k++) {
// 방향 탐색.
int nRowPoint = mazeTemp.nRow + dr[k];
int nColPoint = mazeTemp.nCol + dc[k];
int nCount = mazeTemp.nCount;
if(nRowPoint < 0 || nRowPoint >= nRows || nColPoint < 0 || nColPoint >= nCols ||
bIsSearched[nRowPoint][nColPoint])
continue;
bIsSearched[nRowPoint][nColPoint] = true;
// 다음 방향이 1이면 이동, qBuffer에 저장.
if(barrMaze[nRowPoint][nColPoint]) {
nCount++;
qBuffer.add(new MazeInform(nRowPoint, nColPoint, nCount));
}
// 도착 했을 경우, 최소값 비교 ( 최소 경로 )
if(nRowPoint == nRows-1 && nColPoint == nCols-1 && nMin > nCount)
nMin = nCount;
}
}
System.out.println(nMin);
}
}
이론을 하나씩 하나씩 점검해보면서 구현 전에 설계해보구 코드를 작성하니 정~~~~말 시간이 오래걸리네요. 심지어 이제 좀 어떤지 알 것 같은 느낌이라 앞으로도 bfs문제를 조금 더 풀어봐야 확실히 알 것 같습니다. 알고리즘 정말 쉽지 않네요.
긴 글 읽어주셔서 감사합니다!
Good Luck! (피드백 고맙습니다)
'※ 백준 (Baekjoon) > [Java] 문제 풀이 ( Solve the problems)' 카테고리의 다른 글
[브론즈 1] 2609. 최대공약수와 최소공배수 (Java) (0) | 2023.08.01 |
---|---|
[브론즈 2] 2747. 피보나치 (Java) (0) | 2023.07.31 |
[실버5] 1316. 그룹 단어 체커 (Java) (0) | 2023.07.30 |
[실버5] 7568. 덩치 (Java) (0) | 2023.07.30 |
[실버4] 2578. 빙고 (Java) (0) | 2023.07.28 |