티스토리 뷰
1. 문제
https://www.acmicpc.net/problem/16236
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가
www.acmicpc.net
2. 풀이
BFS를 통해 상어의 위치를 이동해가며, 먹을 수 있는 물고기 중 가장 작은 거리를 선택하고 더이상 먹을 수 없는 물고기가 없을 때까지 이 과정을 반복해 답을 구한다. 전체적인 풀이 과정은 아래와 같다.
- 상어의 위치를 저장하고, 상어의 위치에서부터 탐색을 시작한다.
- 상어의 위치에서 BFS를 해 상어의 위치를 이동시킨다. 상어가 갈 수 있는 경우는 (1) 상어의 크기보다 작아 물고기를 먹을 수 있는 경우 (2) 빈공간이거나 상어 크기와 같아 물고기를 지날 수 있는 경우로 2가지다. 이 중, 먹을 수 있는 경우 물고기의 좌표와 그때의 시간(거리)를 저장(fishList)한다.
- 더이상 먹을 수 있는 물고기가 없으면(fishList.isEmpty() == true) 이때까지의 시간을 출력한 후 종료한다.
- 더이상 먹을 수 있는 물고기가 있으면 물고기의 목록을 우선순위에 맞게 정렬한다. 정렬하면 가장 앞에 있는 물고기가 우선순위가 가장 높으므로 해당 물고기를 먹을 물고기(fishToEat)로 정한다.
- 거리 오름차순 -> x 좌표 오름차순 -> y좌표 오름차순으로 정렬한다. Comparator를 사용해 정렬한다.
- 해당 물고기를 먹는데까지 걸린 시간을 전체 걸린 시간(time)에 추가한다. 먹은 물고기의 갯수를 증가시키고 map에서 0으로 처리해 물고기를 먹었음을 표시한다. 현재 상어의 위치를 갱신한다.
- 상어의 크기와 현재까지 먹은 물고기 갯수가 같으면 상어가 커질 수 있는 조건이므로 상어의 크기를 증가시킨다.
- 더이상 먹을 물고기가 없을때까지 1~4의 과정을 반복한다.
3. 코드
import java.util.*;
import java.io.*;
class Main{
static int n;
static int[][] map;
static Fish shark;
// 먹이가 될 물고기
private static class Fish{
int x, y, dist;
public Fish(int x, int y, int dist){
this.x = x;
this.y = y;
this.dist = dist;
}
}
// bfs
private static void solve(){
Queue<Fish> q = new LinkedList<>();
boolean[][] visited = new boolean[n][n]; // 방문여부 체크
int time = 0; // 물고기를 잡아먹을 수 있는 시간
ArrayList<Fish> fishList = new ArrayList<Fish>(); // 먹을 수 있는 물고기
int nowSize = 2; // 상어 크기
int fishCnt = 0; // 먹은 물고기 갯수
int[][] dir = {{0,1},{1,0},{-1,0},{0,-1}};
while(true){
visited = new boolean[n][n];
visited[shark.x][shark.y] = true;
q.add(shark);
while(!q.isEmpty()){
Fish now = q.poll();
for(int i = 0; i < 4; i++){
int nX = now.x + dir[i][0];
int nY = now.y + dir[i][1];
if(nX < 0 || nY < 0 || nX >= n || nY >= n) continue;
if(visited[nX][nY]) continue;
if(map[nX][nY] != 0 && map[nX][nY] < nowSize){ // 먹을 수 있는 경우
fishList.add(new Fish(nX, nY, now.dist+1));
q.add(new Fish(nX, nY, now.dist+1));
visited[nX][nY] = true;
}else if(map[nX][nY] == 0 || map[nX][nY] == nowSize){ // 지날 수 있는 경우
q.add(new Fish(nX, nY, now.dist+1));
visited[nX][nY] = true;
}
}
}
if(fishList.isEmpty()){ // 더이상 먹을 물고기가 없는 경우
System.out.println(time);
return;
}else{
// 거리 -> x좌표 -> y좌표 오름차순 정렬
Collections.sort(fishList, new Comparator<Fish>(){
@Override
public int compare(Fish f1, Fish f2){
if(f1.dist == f2.dist) {
if(f1.x == f2.x){
return Integer.compare(f1.y, f2.y);
}else{
return Integer.compare(f1.x, f2.x);
}
}else{
return Integer.compare(f1.dist, f2.dist);
}
}
});
}
Fish fishToEat = fishList.get(0); // 먹을 물고기
time += fishToEat.dist; // 먹은 물고기의 거리를 time에 추가
fishCnt++; // 먹은 물고기의 갯수 카운트
map[fishToEat.x][fishToEat.y] = 0; // 물고기 먹음 처리
if(nowSize == fishCnt){
nowSize++;
fishCnt = 0;
}
shark.x = fishToEat.x;
shark.y = fishToEat.y;
fishList.clear();
}
}
public static void main (String[] args) throws java.lang.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[] input = br.readLine().split(" ");
for(int j = 0; j < n; j++){
map[i][j] = Integer.parseInt(input[j]);
if(map[i][j] == 9){ // 아기상어 위치
shark = new Fish(i, j, 0);
map[i][j] = 0;
}
}
}
solve();
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[JAVA/DFS,BFS] 백준 14502 연구소 (0) | 2021.10.22 |
---|---|
[JAVA/백트래킹] 백준 14888 연산자 끼워넣기 (0) | 2021.10.21 |
[JAVA/백트래킹] 백준 15686 치킨 배달 (0) | 2021.10.18 |
[JAVA/DP] 백준 14501 퇴사 (0) | 2021.10.18 |
[JAVA/스택] 백준 2493 탑 (0) | 2021.10.11 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- c++
- java
- mysql
- dovecot
- 메일서버
- the pads
- hackerrank
- 2981
- FTP
- 백준
- ESP8266
- git
- 집배원 한상덕
- 자바
- 키 순서
- 워드프레스
- 스티커모으기2
- 리눅스
- BFS
- 라즈베리파이
- hc-06
- 합승 택시 요금
- dht11
- 아두이노
- DP
- 구슬 탈출2
- 프로그래머스
- 11503
- 블루투스
- 라즈비안
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함