백준 알고리즘(BOJ)

BOJ_17086_아기 상어2

꼬꼬랑내 2021. 9. 15. 07:43

1

구분: 그래프 이론, 그래프 탐색, BFS, DFS
언어: Java
전략:

  • 상어와 그 주변(8방)을 BFS를 통해 탐색하면서, 그 값을 갱신한다.
  • 어떤 지점의 안전거리는 나를 부른(내 주변, 나를 인접해하는) 것보다 1 크다 -> 나를 부른 것의 값+1 
  • 상어가 있는 자리를 -1로 처음 설정하여 +1 할 때, 진짜 값과 상어의 값의 혼란을 줄인다. 
  • 최대 값을 매번 갱신한다. 현 최대 값과, 새로 갱신되는 map의 값을 비교한다.

2. 코드

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
	
	//배열의 x,y좌표를 담는 class 생성
	static class Node{
		int y;
		int x;
		Node(int y, int x){
			this.y = y;
			this.x = x;
		}
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int h = scanner.nextInt(); //높이
		int w = scanner.nextInt(); //너비
		
		int[][] map = new int[h][w];
		for(int i = 0; i<h; i++) {
			for(int j = 0; j<w; j++) {
				int input = scanner.nextInt();
				if(input ==1){ //상어가 있는 자리는 -1로 설정
					map[i][j] = -1;
				}
				else map[i][j] = input;
			}
		}
		Queue<Node> q = new LinkedList<>();
		
		for(int i = 0; i<h; i++) {
			for(int j = 0; j<w; j++) {
				if(map[i][j]==-1)
				//상어가 있는 곳을 큐에 삽입
				q.offer(new Node(i,j));
			}
		}
		
		//시계방향 - 8방 탐색
		int[] dx = {0,1,1,1,0,-1,-1,-1};
		int[] dy = {-1,-1,0,1,1,1,0,-1};
		//구하고자 하는 최대값
		int max = Integer.MIN_VALUE;
		
		while(!q.isEmpty()) {
			
			//뺴낸다
			Node node = q.poll();
			int py = node.y;
			int px = node.x;
			
			//뿌리가 되는 칸의 값 - 인접한 값들은 prev에서 1씩 증가한 거리를 가짐
			int prev = map[py][px];
			//상어가 있는 자리면 0으로 처리
			if(prev == -1) prev = 0;
			
			//8방 탐색
			for(int d = 0; d<8; d++) {
				//인접한 노드의 좌표를 구함
				int nx = px + dx[d];
				int ny = py + dy[d];
				
				//범위를 벗어나거나 아기상어면 지나가
				if(nx<0||ny<0||nx>=w||ny>=h || map[ny][nx]==-1)
					continue;
				//이미 채워져 있는곳이야 - 지나가 
				if(map[ny][nx]!=0) continue;
				
				//인접한 곳들을 큐에 삽입, 그 자리의 값을 상어와의 거리로 갱신
				q.offer(new Node(ny, nx));
				map[ny][nx] = prev+1;
				
				//매번 최대값을 갱신한다. 
				max = Math.max(max, map[ny][nx]);
				
			}//8방탐색
		}//while

		System.out.println(max);

	}//main
	
}//class

3

처음에는 상어 하나를 기준으로 BFS적용, 그 다음 적용, 하면서 만약 상어와 0이 아니면(이미 갱신 되어 있으면) 현재의 값과, 새로 갱신하려는 값의 최소 값으로 map을 변경하는 로직을 세웠다. 하지만 무한 루프에 빠져서 이 방법을 버렸다.