꾸물꾸물 졔의 개발공부

[백준] 2665 미로만들기 - JAVA 본문

알고리즘/백준

[백준] 2665 미로만들기 - JAVA

체제 2023. 8. 23. 15:26

https://www.acmicpc.net/problem/2665

 

2665번: 미로만들기

첫 줄에는 한 줄에 들어가는 방의 수 n(1 ≤ n ≤ 50)이 주어지고, 다음 n개의 줄의 각 줄마다 0과 1이 이루어진 길이가 n인 수열이 주어진다. 0은 검은 방, 1은 흰 방을 나타낸다.

www.acmicpc.net

🌟1261 알고스팟 문제와 거의 유사하다. 

 

 

[알고리즘]

  • 검은 방을 최소한으로 흰방으로 바꾸고 이동하기 위해 최소비용 BFS 알고리즘 적용 

 

[설계]

  • 2차원 배열의 (0,0) 부터 이동 
    1. 검은 방: 흰방으로 바꾸고 (map[x][y] = 1) , 바꾼 방 갯수+1 후 이동 
    2. 흰 방: 그냥 이동
  • 우선순위큐에 의해 가장 먼저 (n-1, n-1) 나왔을 때, 바꾼 방의 갯수가 최소값 (=답) 
  • Room 클래스 
    1. 현재 위치, 현재까지 바꾼 방의 총 갯수 저장 
    2. Comparable 인터페이스를 구현하여 방 갯수 오름차순 정렬 
    3. 우선순위큐에 저장, 방의 갯수가 적을 수록 우선순위 ↑

 

[구현 과정]

  • map[][] : 바둑판 모양의 방 정보를 저장할 int형 배열 (0은 검은방, 1은 흰 방)
  • Room 클래스 : (x,y) = 위치, change = (x,y)까지 이동하는데에 바꾼 방의 갯수 

 

1. 입력받은 바둑판 모양의 방 정보를 map 배열에 저장 

 

2. 시작 위치인 map[0][0] 에서 BFS 탐색 시작 

 

3. Room 클래스를 담고 있는 우선순위큐와, 방문체크를 위한 visited 배열을 생성한다. 출발점을 큐에 add하고 방문체크 후 시작 

 

4. 큐가 빌 때까지 아래 과정을 반복한다. (bfs 탐색) 

  • 큐에서 하나 poll (=큐에 들어있는 Room 객체 중 바꾼 방의 갯수가 가장 적은 것) 
  • poll 한 위치가 목적지인 [n-1][n-1] 이라면, 바꾼 방의 갯수(change) 반환. (=우선순위큐에 의해 최소 갯수)
  • 그렇지 않다면 사방탐색하며 이동 
    1. 만약 이동한 위치가 map 범위를 벗어나거나 방문했던 곳이라면 continue 
    2. 검은 방(=0) 일 경우: 흰 방(1)으로 바꾸고, 방문체크 후 큐에 삽입 (바꾼 방 갯수 change+1)
    3. 흰 방(=1) 일 경우: 방문체크 후 큐에 삽입 

 

 

5. 목적지까지 다다르는데 최소한으로 바꾼 방의 갯수, 즉 BFS 결과 그대로 출력 

 


 

[소스 코드]

import java.util.*;
import java.io.*;

public class Main {
	static int n;
	static int map[][]; 
	static int[] dx= {-1,1,0,0};
	static int[] dy= {0,0,-1,1};

	static class Room implements Comparable<Room>{
		int x;
		int y;
		int change;
		
		public Room(int x, int y, int change) {
			this.x=x;
			this.y=y;
			this.change=change;
		}

		@Override
		public int compareTo(Room o) {
			return this.change- o.change;
		}
	}
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
	
		n = Integer.parseInt(br.readLine()); 
		
		map= new int[n][n];
		for(int i=0; i<n; i++) {
			String s= br.readLine();
			for(int j=0; j<n; j++) {
				map[i][j] = s.charAt(j)-'0';  
			}
		}
		
		System.out.println(bfs()); 
		
		
	}//end of main
	
	private static boolean isOut(int x, int y) {
		return x<0 || x>=n ||y<0 || y>=n;
	}
	private static int bfs() {
		PriorityQueue<Room> que= new PriorityQueue<>();
		boolean visited[][] = new boolean[n][n]; 
		
		que.add(new Room(0,0,0));
		visited[0][0] = true; 
		
		while(!que.isEmpty()) {
			Room r= que.poll();
			int x= r.x;
			int y= r.y;
			int change= r.change;
			
			if(x==n-1 && y==n-1) return change; 
			
			for(int d=0; d<4; d++) {
				int nx = x+dx[d];
				int ny = y+dy[d];
				
				if(isOut(nx, ny)|| visited[nx][ny]) continue;
				
				visited[nx][ny] = true;
				//검은방일 경우, 흰방으로 바꾸어야함 
				if(map[nx][ny]==0) {
					map[nx][ny]=1; 
					que.add(new Room(nx,ny,change+1)); 
				}
				else que.add(new Room(nx,ny,change)); 
			}
 		}
		
		return -1;
	}
}//end of class

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 17609 회문 - JAVA  (0) 2023.08.25
[백준] 1253 좋다 - JAVA  (1) 2023.08.24
[백준] 1261 알고스팟 - JAVA  (0) 2023.08.22
[백준] 1504 특정한 최단 경로 - JAVA  (0) 2023.08.21
[백준] 5972 택배 배송 - JAVA  (0) 2023.08.17