일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- COS Pro
- StringTokenizer
- 버퍼
- lv2
- 프로그래머스 자바
- 스택
- 이진수 변환
- 프로그래머스 문자열 정렬
- Lv1
- 스프링부트 도커
- 큐
- 프로그래머스 풀이
- 문자열
- Programmers
- index of
- Stack
- Queue
- lv0
- 클라이언트
- 백준 N과 M 자바
- 알고리즘
- 스프링부트 도커로 배포
- java
- 스프링부트 도커 배포
- 백준
- 삼각형의 완성조건
- 프로그래머스
- 자바
- SWEA
- 오름차순 정렬
- Today
- Total
mun dev
[백준] 2665 미로 만들기 자바(Java) 본문
문제설명
n×n 바둑판 모양으로 총 n2개의 방이 있다. 일부분은 검은 방이고 나머지는 모두 흰 방이다. 검은 방은 사면이 벽으로 싸여 있어 들어갈 수 없다. 서로 붙어 있는 두 개의 흰 방 사이에는 문이 있어서 지나다닐 수 있다. 윗줄 맨 왼쪽 방은 시작방으로서 항상 흰 방이고, 아랫줄 맨 오른쪽 방은 끝방으로서 역시 흰 방이다.
시작방에서 출발하여 길을 찾아서 끝방으로 가는 것이 목적인데, 아래 그림의 경우에는 시작방에서 끝 방으로 갈 수가 없다. 부득이 검은 방 몇 개를 흰 방으로 바꾸어야 하는데 되도록 적은 수의 방의 색을 바꾸고 싶다.
아래 그림은 n=8인 경우의 한 예이다.
위 그림에서는 두 개의 검은 방(예를 들어 (4,4)의 방과 (7,8)의 방)을 흰 방으로 바꾸면, 시작방에서 끝방으로 갈 수 있지만, 어느 검은 방 하나만을 흰 방으로 바꾸어서는 불가능하다. 검은 방에서 흰 방으로 바꾸어야 할 최소의 수를 구하는 프로그램을 작성하시오.
단, 검은 방을 하나도 흰방으로 바꾸지 않아도 되는 경우는 0이 답이다.
입력
첫 줄에는 한 줄에 들어가는 방의 수 n(1 ≤ n ≤ 50)이 주어지고, 다음 n개의 줄의 각 줄마다 0과 1이 이루어진 길이가 n인 수열이 주어진다. 0은 검은 방, 1은 흰 방을 나타낸다.
출력
첫 줄에 흰 방으로 바꾸어야 할 최소의 검은 방의 수를 출력한다.
풀이
BFS를 사용해서 풀이해야 하는 건 알 수 있었지만, visited를 boolean으로 선언하는 것이 아닌 int형으로 위치마다 방을 바꾼 횟수를 저장 시켜야한다.
시작할 때 visited배열을 최대 값으로 최가화하고, BFS를 진행하며 최소값을 저장해나가는 것이 중요하다.
벽을 만났을 때, 해당 벽을 기준으로 위치 값을 +1증가 시키며 탐색을 진행한다.
BFS는 상, 하, 좌, 우 돌아가면서 같은 위치가 여러번 들어오지만 이때 가장 최소 값을 저장한다.
(이미 값이 존재하고, 새로 들어온 값보다 작다면 continue)
통과한 코드 ✅
import java.util.*;
import java.io.*;
public class Main {
public static int n;
public static int map[][];
public static int visited[][];
public static int dx[] = {0, 0, -1, 1};
public static int dy[] = {1, -1, 0, 0};
public static class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
map = new int[n][n];
visited = new int[n][n];
for (int i = 0; i < n; i++) {
String s = br.readLine();
String strArr[] = s.split("");
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(strArr[j]);
visited[i][j] = Integer.MAX_VALUE;
}
}
bfs();
System.out.println(visited[n - 1][n - 1]);
}
public static void bfs() {
Queue<Node> queue = new LinkedList<>();
queue.offer(new Node(0, 0));
visited[0][0] = 0;
while (!queue.isEmpty()) {
Node node = queue.poll();
for (int i = 0; i < 4; i++) {
int cx = node.x + dx[i];
int cy = node.y + dy[i];
if (cx >= 0 && cy >= 0 && cx < n && cy < n) {
// 옮기기 전의 값 보다 옮긴 값에 이미 더 작은 값이 들어있다면 continue
if (visited[cx][cy] <= visited[node.x][node.y]) continue;
// 이동할 수 있는 곳이면 visited는 이전값을 넣어줌
if (map[cx][cy] == 1) {
queue.offer(new Node(cx, cy));
visited[cx][cy] = visited[node.x][node.y];
} else {
// 이동할 수 없는 벽이면 값을 +1
queue.offer(new Node(cx, cy));
visited[cx][cy] = visited[node.x][node.y] + 1;
}
}
}
}
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1406 에디터 자바(Java) (0) | 2023.11.13 |
---|---|
[백준] 9375 패션왕 신혜빈 자바(Java) (1) | 2023.11.13 |
[백준] 1182 부분수열의 합 자바(Java) (0) | 2023.11.10 |
[백준] 7569 토마토 자바(Java) (0) | 2023.11.07 |
[백준] 21736 헌내기는 친구가 필요해 자바(Java) (0) | 2023.11.06 |