본문 바로가기
백준

백준 17086번 : 아기 상어2

by Huiyeong 2021. 3. 9.

 문제

www.acmicpc.net/problem/17086

 

17086번: 아기 상어 2

첫째 줄에 공간의 크기 N과 M(2 ≤ N, M ≤ 50)이 주어진다. 둘째 줄부터 N개의 줄에 공간의 상태가 주어지며, 0은 빈 칸, 1은 아기 상어가 있는 칸이다. 빈 칸의 개수가 한 개 이상인 입력만 주어진다.

www.acmicpc.net

17086 아기 상어2

 

 구현 방법

 처음에는 브루트포스로 구할 수 있는 전부를 구했습니다. 각자의 위치에서 bfs를 통해 제일 가까운 상어까지의 거리를 저장 후 최댓값을 구해주었습니다.

 

채점 후 시간차가 많이 나는 코드를 참고해보니 다른 생각으로 접근할 수 있다는 걸 깨달았고 참고해서 다시 짜보았습니다.

빈 칸이 중점이 아닌 상어를 중점으로 하여 입력되는 상어를 전부 queue에 넣어준 후 bfs를 통해 방문체크를 해주면 퍼지다가 알아서 방문한곳을 만나 멈춥니다. 그 멈춘 구간이 해당 상어에서 최대로 먼 부분이기 때문에 카운트를 체크한 변수를 따로 최댓값인지 비교할 필요 없이 그대로 출력해주면 끝입니다.

 

 구현 코드

- 빈 칸 중점

package BOJ.Silver.bfsdfs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class B17086_아기상어2 {
	static int R, C, MAX;
	static int[][] map, deltas= {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
	static Queue<move> bfs;
	static int[][] check;
	static class move{
		int r, c, cnt;

		public move(int r, int c, int cnt) {
			super();
			this.r = r;
			this.c = c;
			this.cnt = cnt;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		map = new int[R][C];
		check = new int[R][C];
		for (int r=0;r<R;r++) {
			st = new StringTokenizer(br.readLine());
			for (int c=0;c<C;c++) {
				map[r][c] = Integer.parseInt(st.nextToken());
			}
		}
		MAX = Integer.MIN_VALUE;
		for (int r=0;r<R;r++) {
			for (int c=0;c<C;c++) {
				if (map[r][c]==0) { // 빈칸일 때 bfs 돌리기
					bfs = new LinkedList<>();
					bfs.add(new move(r, c, 1));
					bfsL();
					check = new int[R][C];
				}
			}
		}
		
		System.out.println(MAX);
	}
	
	static void bfsL() {
		while(!bfs.isEmpty()) {
			int size = bfs.size();
			for (int i=0;i<size;i++) {
				move now = bfs.poll();
				for (int d=0;d<8;d++) {
					int nr = now.r+deltas[d][0];
					int nc = now.c+deltas[d][1];
					if (isIn(nr,nc) && check[nr][nc]==0) {
						if (map[nr][nc]==1) { // 상어를 발견하면 최댓값 구하고 끝내기
							MAX = Math.max(MAX, now.cnt); 
							return;
						}
						check[nr][nc]=1;
						bfs.offer(new move(nr, nc, now.cnt+1));
					}
				}
			}
		}
	}
	
	static boolean isIn(int nr, int nc) {
		return nr>=0 && nr<R && nc>=0 && nc<C;
	}
}

- 상어 중점

package BOJ.Silver.bfsdfs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class B17086_아기상어2 {
	static int R, C, cnt;
	static int[][] map, deltas= {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
	static Queue<int[]> bfs;
	static boolean[][] visit;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		map = new int[R][C];
		visit = new boolean[R][C];
		bfs = new LinkedList<>();
		for (int r=0;r<R;r++) {
			st = new StringTokenizer(br.readLine());
			for (int c=0;c<C;c++) {
				map[r][c] = Integer.parseInt(st.nextToken());
				if (map[r][c]==1) { // 상어일 때
					bfs.add(new int[] {r, c}); // 다 넣어주기
 					visit[r][c] = true;
				}
			}
		}
		bfsL();
		
		System.out.println(cnt-1);
	}
	
	static void bfsL() {
		while(!bfs.isEmpty()) {
			cnt++;
			int size = bfs.size();
			for (int i=0;i<size;i++) {
				int[] now = bfs.poll();
				for (int d=0;d<8;d++) {
					int nr = now[0]+deltas[d][0];
					int nc = now[1]+deltas[d][1];
					if (isIn(nr,nc) && visit[nr][nc]==false) {
						visit[nr][nc] = true;
						bfs.offer(new int[] {nr, nc});
					}
				}
			}
		}
	}
	
	static boolean isIn(int nr, int nc) {
		return nr>=0 && nr<R && nc>=0 && nc<C;
	}
}

 

정답!

 

'백준' 카테고리의 다른 글

백준 3184번 : 양  (0) 2021.03.09
백준 5567번 : 결혼식  (0) 2021.03.09
백준 10815번 : 숫자 카드  (0) 2021.03.07
백준 10026번 : 적록색약  (0) 2021.03.07
백준 2960번 : 에라토스테네스의 체  (0) 2021.03.07