본문 바로가기
백준/탐색(BFS, DFS)

백준 16236번 아기상어

by 기초백과 2021. 1. 13.

www.acmicpc.net/problem/16236

 

16236번: 아기 상어

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가

www.acmicpc.net

오늘 풀어본 문제는 백준의 16236번 아기상어입니다.

알고리즘 분류는 아래와 같습니다.

  • 구현
  • 그래프 이론
  • 그래프 탐색
  • 시뮬레이션
  • 너비 우선 탐색

답으로 상어가 먹을 수 있는 먹이가 다 떨어지는 시점을 제출해야합니다.

제가 구현한 부분은 다음과 같습니다.

  • 상어에게서 가장 가까운 다음 물고기 찾기(물고기 먹을 때마다 BFS를 통해 거리 계산)
  • BFS를 하는 동안 이동하는 칸이라면 이동 경로 큐에 물고기라면 물고기 어레이리스트에 넣음
  • 먹을 수있는 가장 가까운 물고기가 여러 개일 경우 우선 순위 계산(Comparable로 해결)후 정렬
  • 우선 순위가 가장 높은 물고기 먹기(상어 이동, 칸 비우기, 방문 확인 배열 초기화) 
  • 물고기를 먹은 갯수가 자신의 크기와 같은 수가 될때 마다 물고기의 크기 키우기
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.StringTokenizer;

import javax.print.attribute.standard.Finishings;

//백준 아기상어 16236
public class BabyShark16236 {
	int n , time = 0, fishNum = 0, eatCount = 0 ,sharkVal = 2;
	int[][] map;
	boolean[][] visited;
	boolean canEat = true;
	Points sharkPoint;
	ArrayList<Points> fishs = new ArrayList<>();
	Queue<Points> loadQueue = new LinkedList<>();
	
	//숫자 입력
	public void setNum() {
		int i, j;
		try {
			BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
			StringTokenizer st = new StringTokenizer(bf.readLine());
			
			n = Integer.parseInt(st.nextToken());
			
			map = new int[n][n];
			visited = new boolean[n][n];
			
			for(i = 0; i<n; i++) {
				st = new StringTokenizer(bf.readLine());
				
				for(j=0; j<n; j++) {
					map[i][j] = Integer.parseInt(st.nextToken());
					
					if(map[i][j] == 9) {
						sharkPoint = new Points(i, j);
						map[i][j] = 0;
					}else if(map[i][j] != 0) {
						fishNum++;
					}	
				}
			}
		}catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	//다음 물고기 찾기
	public void searchFish() {
		int i,j, queueSize, x, y;
		Points nowPoint;
		loadQueue.add(sharkPoint);
		visited[sharkPoint.y][sharkPoint.x] = true;
		int distance = 0;
		

		while(!loadQueue.isEmpty()) {
			distance++;
			queueSize = loadQueue.size();
			
			for(i=0; i<queueSize; i++) {
				nowPoint = loadQueue.remove();
				
				x = nowPoint.x;
				y = nowPoint.y;
				
				if(y+1 < n && !visited[y+1][x] && map[y+1][x] <= sharkVal) {
					checkFish(y+1, x);
				}if(y -1 >= 0 && !visited[y-1][x] && map[y-1][x] <= sharkVal) {
					checkFish(y-1, x);
				}if(x + 1 < n &&!visited[y][x+1] && map[y][x+1] <= sharkVal) {
					checkFish(y, x+1);
				}if(x-1 >= 0 && !visited[y][x-1] && map[y][x-1] <= sharkVal) {
					checkFish(y, x-1);
				}
			}
			if(!fishs.isEmpty()) {
				break;
			}
		}
		loadQueue.clear();
		if(!fishs.isEmpty()) {
			time += distance;
		}else {
			canEat = false;
		}
		
	}
	
	public void eatFish() {
		int i, j;
		fishs.sort(Comparator.naturalOrder());
		Points eatFishPoint = fishs.get(0);
		
		sharkPoint = eatFishPoint;
		map[sharkPoint.y][sharkPoint.x] = 0;
		
		eatCount++;
		fishNum--;
		if(eatCount%sharkVal == 0) {
			eatCount = 0;
			sharkVal++;
		}
		
		fishs.clear();
		for(i=0; i<n; i++)
			Arrays.fill(visited[i], false);
	}
	
	public void checkFish(int y, int x) {
		visited[y][x] = true;
		if(sharkVal > map[y][x] && map[y][x] != 0) {
			fishs.add(new Points(y, x));
		}else {
			loadQueue.add(new Points(y, x));
		}
	}
	
	public class Points implements Comparable<Points>{
		int x,y, distance;
		public Points(int y, int x) {
			this.x = x;
			this.y = y;
		}
		
		@Override
		public int compareTo(Points o) {
			// TODO Auto-generated method stub
			
	
		if(this.y > o.y) {
			return 1;
		}else if(this.y < o.y) {
			return -1;
		}else if(this.y == o.y) {
			if(this.x > o.x) {
				return 1;
			}else{
				return -1;
			}
		}
		
		return 0;
		}		
	}
	
	
	
	public static void main(String args[]) {
		BabyShark16236 main = new BabyShark16236();
		main.setNum();
		boolean canEat;
		//System.out.println(main.fishNum);
		while(main.fishNum != 0) {
			main.searchFish();
			
			if(!main.canEat)
				break;
			else {
				main.eatFish();
			}
		}
		System.out.println(main.time);
	
	}
}

반성할 점

  • 변수가 너무 많아져 나도 헷갈린다.
  • 노트에 적으면서 정리하면서 코드 짜기
  • 시간 복잡도 공간 복잡도 계산하면서 하기

'백준 > 탐색(BFS, DFS)' 카테고리의 다른 글

백준 11559번 PuyoPuyo  (0) 2021.01.17
백준 2583번 영역 구하기  (0) 2021.01.14
백준 2636, 2638번 치즈  (0) 2021.01.14
백준 2468번 안전 영역  (0) 2021.01.14
백준 14502번 연구소  (0) 2021.01.13