알고리즘
백준 19237번 어른 상어 (JAVA)
박카스마시며코딩
2022. 4. 4. 16:52
https://www.acmicpc.net/problem/19237
19237번: 어른 상어
첫 줄에는 N, M, k가 주어진다. (2 ≤ N ≤ 20, 2 ≤ M ≤ N2, 1 ≤ k ≤ 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미
www.acmicpc.net
저는 BFS를 이용해 문제를 해결하였습니다.
저는 이동할 때 해당 좌표가 빈칸인지 또는 자신보다 값이 낮은 상어가 있는지를 확인 (번호가 낮은 순서대로 상어를 움직였습니다.)하고 그 다음에 자신의 냄새인지를 확인하였습니다. 모든 상어가 이동하고 현재의 값을 냄새를 체크하였습니다.
저는 상어가 이동하면서 현재 냄새를 남겨 계속 테스트 케이스에서 틀렸었습니다.
package BOJ.Simulation;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_19237 {
private static class Smell{
int num;
int time;
public Smell(int num, int time) {
this.num = num;
this.time = time;
}
}
private static class Shark{
int num;
int y;
int x;
int dir;
int[][] priorityDir;
public void setDir(int dir){
this.dir = dir;
}
public Shark(int num,int y, int x) {
this.num = num;
this.y = y;
this.x = x;
priorityDir = new int[4][4];
}
public void setPriorityDir(int index, int[] arr) {
this.priorityDir[index] = arr;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
Function<String,Integer> stoi = Integer::parseInt;
int n = stoi.apply(st.nextToken());
int m = stoi.apply(st.nextToken());
int k = stoi.apply(st.nextToken());
int[][] map = new int[n][n];
Shark[] input = new Shark[m];
for(int i = 0 ; i < n ; i++){
st = new StringTokenizer(br.readLine()," ");
for(int j = 0 ; j < n ; j++){
map[i][j] = stoi.apply(st.nextToken());
if(map[i][j] != 0){
input[map[i][j]-1] = new Shark(map[i][j],i,j);
}
}
}
st = new StringTokenizer(br.readLine()," ");
for(int i = 0 ; i < m ; i++){
int dir = stoi.apply(st.nextToken()) - 1;
input[i].setDir(dir);
}
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < 4 ; j++){
st = new StringTokenizer(br.readLine()," ");
int[] tempDir = new int[4];
Shark shark = input[i];
for(int l = 0 ; l < 4 ; l++){
tempDir[l] = stoi.apply(st.nextToken())-1;
}
shark.setPriorityDir(j,tempDir);
}
}
int result = cal(map,input,n,m,k);
System.out.println(result);
}
private static int cal(int[][] map, Shark[] input, int n, int m, int k) {
int time = 0;
Smell[][] smell = new Smell[n][n];
Queue<Shark> q = new LinkedList<>();
for(int i = 0 ; i < m; i++){
q.offer(input[i]);
smell[input[i].y][input[i].x] = new Smell(input[i].num,-1);
}
while(q.size() > 1){
int size = q.size();
// System.out.println(size);
// print(map,n);
// System.out.println();
// printSmell(smell,n);
for(int s = 0 ; s < size ; s++){
Shark now = q.poll();
if(move(now,map,n,smell,time)){
q.offer(now);
}
// System.out.println(now.num+" "+now.y+" "+now.x);
}
makeSmell(smell,time,q);
time++;
removeSmell(smell,n,time,k);
if(time > 1_000){
return -1;
}
}
return time;
}
private static void makeSmell(Smell[][] smell, int time, Queue<Shark> q) {
int size = q.size();
for(int i = 0 ; i < size ; i++){
Shark now = q.poll();
smell[now.y][now.x] = new Smell(now.num,time);
q.offer(now);
}
}
private static void removeSmell(Smell[][] smell, int n, int time, int k) {
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(smell[i][j] != null && smell[i][j].time < time - k){
smell[i][j] = null;
}
}
}
}
private static void printSmell(Smell[][] smell, int n) {
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(smell[i][j]!= null){
System.out.print(smell[i][j].num+" ");
}else{
System.out.print(0+" ");
}
}
System.out.println();
}
}
private static void print(int[][] arr, int n) {
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
private static final int[] dy = {-1,1,0,0};
private static final int[] dx = {0,0,-1,1};
private static boolean move(Shark now, int[][] map, int n,Smell[][] smell,int time) {
int dir = now.dir;
int num = now.num;
for(int i = 0 ; i < 4 ; i++){ // 0
int nextDir = now.priorityDir[dir][i];
int ny = now.y + dy[nextDir];
int nx = now.x + dx[nextDir];
if(ny >= 0 && ny < n && nx >= 0 && nx < n ){
if(smell[ny][nx] != null){
continue;
}
if(map[ny][nx] != 0 && map[ny][nx] < num){
map[now.y][now.x] = 0;
return false;
}
map[ny][nx] = num;
map[now.y][now.x] = 0;
// smell[ny][nx] = new Smell(num,time);
now.y = ny;
now.x = nx;
now.dir = nextDir;
return true;
}
}
for(int i = 0 ; i < 4 ; i++){ // 자신 냄새
int nextDir = now.priorityDir[dir][i];
int ny = now.y + dy[nextDir];
int nx = now.x + dx[nextDir];
if(ny >= 0 && ny < n && nx >= 0 && nx < n && smell[ny][nx].num == num){
// System.out.println("smell same "+smell[ny][nx].num+" "+num);
// System.out.println(ny+" "+nx);
map[ny][nx] = num;
map[now.y][now.x] = 0;
// smell[ny][nx] = new Smell(num,time);
now.y = ny;
now.x = nx;
now.dir = nextDir;
return true;
}
}
return true;
}
}