https://www.acmicpc.net/problem/2636
접근법
오랜만에 감 다시 잡아야해서 살짝 쉬운문제로 꺼냈다
기본적인 BFS로 풀었다
1. 치즈가 모두 녹았는지 체크해서 모두 0이면, 반복문 종료
1-1. checkZero로 그냥 배열 탐색해서 0이 아니면 바로 false 리턴시키고, while 문 진입
2. TIME변수 값 증가시킴으로 시간흐름
현재 치즈배열을 로직에 따라 1시간 후 치즈로 변경 cheese = bfs(cheese)
3. bfs안에서는 우선 현재 치즈덩어리 개수를 MASS에 기록해둠
(0,0)에는 치즈가 놓이지 않은 공기 공간이니까 여기를 bfs로 탐색해서 구멍인 공간(0)과 외부공간(2)로 구분함
retArray를 주석에 설명한대로 완성해서 리턴함
소스
import java.util.*;
import java.io.*;
public class Main {
static int N;
static int M;
static int TIME = 0;
static int MASS = 0;
static int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}};
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
int[][] cheese = new int[N][M];
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0; j < M; j++) {
cheese[i][j] = Integer.parseInt(st.nextToken());
}
}
while(!checkZero(cheese)) {
TIME++;
cheese = bfs(cheese);
}
System.out.println(TIME);
System.out.println(MASS);
}
static boolean checkZero(int[][] array) {
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(array[i][j] != 0) return false;
}
}
return true;
}
static int[][] bfs(int[][] array) {
//깊은복사
int[][] newArray = new int[N][M];
int count = 0;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
newArray[i][j] = array[i][j];
if(array[i][j] == 1) count++;
}
}
MASS = count;
//치즈가 놓이지않는 0,0은 무조건 0이므로 이곳부터 bfs로 0인 항목을 모두 2로 바꿔줌
boolean[][] visit = new boolean[N][M];
Queue<Point2636> q = new LinkedList<Point2636>();
visit[0][0] = true;
q.offer(new Point2636(0,0));
newArray[0][0] = 2;
while(!q.isEmpty()) {
Point2636 curP = q.poll();
for(int i = 0; i < 4; i++) {
int nextX = curP.x + dir[i][0];
int nextY = curP.y + dir[i][1];
//범위밖이면 패스
if(nextX < 0 || nextX >= N || nextY < 0 || nextY >= M) continue;
//방문을 안했고 0이면 변경대상
if(!visit[nextX][nextY] && newArray[nextX][nextY] == 0) {
visit[nextX][nextY] = true;
q.offer(new Point2636(nextX, nextY));
newArray[nextX][nextY] = 2;
}
}
}
/* 전체탐색으로 newArray가 2면 0으로(실제 0이니까)
* 1인데 주변에 2가 있으면 0으로 아니면 유지
* 0이면 0으로 유지
* 한 값을 새 retArray에 갱신하고 리턴
*
*/
int[][] retArray = new int[N][M];
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(newArray[i][j] == 0 || newArray[i][j] == 2) retArray[i][j] = 0;
else if(newArray[i][j] == 1) {
if(newArray[i-1][j] == 2 || newArray[i+1][j] == 2 || newArray[i][j-1] == 2 || newArray[i][j+1] == 2) {
retArray[i][j] = 0;
} else {
retArray[i][j] = 1;
}
}
}
}
return retArray;
}
}
class Point2636{
int x;
int y;
Point2636(int x, int y){
this.x = x;
this.y = y;
}
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 - 17070번 파이프 옮기기 1 - java (0) | 2023.08.10 |
---|---|
백준 - 1719번 택배 - java (0) | 2023.08.09 |
백준 - 11048번 이동하기 - java (0) | 2023.08.08 |
백준 - 11779번 최소비용 구하기 2 - java (0) | 2023.08.06 |
백준 - 2623번 음악프로그램 - java (0) | 2023.08.05 |