-
[백준] 16236 아기 상어 (Java)알고리즘/삼성 SW 기출문제 2024. 1. 17. 09:24
https://www.acmicpc.net/problem/16236
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가
www.acmicpc.net
bfs 문제이지만, 몇가지 신경써야 할 점이 있다.
1. 타겟(가까운 물고기)이 복수라면, x좌표가 작은 물고기, 그것 또한 복수라면 y좌표가 작은 물고기를 찾아 이동
2. 아기 상어의 상태인 x, y, size, eat 의 관리
3. eat가 size와 같아 졌을 때 size 증가, eat 초기화
4. 잡아먹은 물고기 좌표값 초기화
5. 아기 상어가 목표를 잃을 때 까지 반복
해결
1. Queue대신 PriorityQueue를 사용하고, 람다를 이용해 정렬기준 변경
2. x, y, 이동 횟수를 클래스에 저장하여 사용하거나, pq에 int[]{x, y, move} 형태로 바로 저장. eat, size 는 변수로 관리
3. 현재 위치인 cur을 검증하여 사냥 가능한 물고기라면 사냥하고 bfs를 break하여 바깥 while문으로 돌아감
바깥 while문에서 size == eat 일 시, size 증가, eat 초기화
4. 3번에서 함께 해결
5. 바깥 while문에서 flag변수를 false로 선언, 안쪽 while문(bfs)에서 사냥을 하지 못하고 빠져나왔다면 바깥 while문 break
import java.io.*; import java.util.*; class Main{ static int[][] board; static int[] dx = {0, 0, -1, 1}; static int[] dy = {-1, 1, 0, 0}; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; int n = Integer.parseInt(br.readLine()); board = new int[n][n]; int[] cur = null; for(int i = 0; i < n; i++){ st = new StringTokenizer(br.readLine()); for(int j = 0; j < n; j++){ board[i][j] = Integer.parseInt(st.nextToken()); if(board[i][j] == 9){ cur = new int[]{i, j}; board[i][j] = 0; } } } int size = 2; int eat = 0; int move = 0; while(true){ PriorityQueue<int[]> q = new PriorityQueue<>((o1, o2) -> o1[2] != o2[2] ? Integer.compare(o1[2], o2[2]) : (o1[0] != o2[0] ? Integer.compare(o1[0], o2[0]) : Integer.compare(o1[1], o2[1])) ); boolean[][] visit = new boolean[n][n]; q.add(new int[]{cur[0], cur[1], 0}); visit[cur[0]][cur[1]] = true; boolean ck = false; while(!q.isEmpty()){ cur = q.poll(); if(board[cur[0]][cur[1]] != 0 && board[cur[0]][cur[1]] < size){ board[cur[0]][cur[1]] = 0; eat++; move += cur[2]; ck = true; break; } for(int i = 0; i < 4; i++){ int nx = dx[i] + cur[0]; int ny = dy[i] + cur[1]; if(nx < 0 || ny < 0 || nx >= n || ny >= n || visit[nx][ny] || board[nx][ny] > size) continue; q.add(new int[]{nx, ny, cur[2] + 1}); visit[nx][ny] = true; } } if(!ck) break; if(size == eat){ size++; eat = 0; } } System.out.println(move); } }
코드만 보면 간단한 문제였지만, 신경쓸게 많아서 많이 헤맸다.
또, 여러 과제를 해결하는 도중이라 변수보다 클래스 변수를 선호하게 되는 경향이 생겨버렸다.
알고리즘을 풀면서는 굉장한 악영향을 끼칠 것 같아 조심해야 겠다.
'알고리즘 > 삼성 SW 기출문제' 카테고리의 다른 글
[백준] 16235 나무 재테크 (Java) (0) 2023.12.15 [백준] 15686 치킨 배달 (Java) (1) 2023.11.29 [백준] 14501 퇴사 (Java) (0) 2023.11.27 [백준] 16234 인구이동 (Java) (1) 2023.11.24