[백준] 19237번 어른 상어 (java, 시뮬레이션)

728x90
반응형

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

상어 주의할 점 

 

사방에 냄새가 있을 경우 자기의 냄새 방향으로 간다.

(자기의 냄새도 사방에 있을 수 있다. 여기서도 우선순위대로 처리해주자.)

 

import java.util.Scanner;

class Place{
	int y,x;

	public Place(int y, int x) {
		super();
		this.y = y;
		this.x = x;
	}
	
}

public class Main {
	static int n,m,k;//k는 냄새 사라지는 초
	static int[] xpos= {0,0,-1,1};//위, 아래 왼 오 
	static int[] ypos= {-1,1,0,0};
	static int[][] map;
	static int[][][] smell;
	static int[][][] sharks;
	static boolean[] isDead;
	static int[] direction;
	static int total;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		k=sc.nextInt();
		map=new int[n][n];
		smell=new int[n][n][2];//상어 번호, 냄새 유효기간
		sharks=new int[m+1][4][4];//상어 번호, 방향, 우선순위
		isDead=new boolean[m+1];
		direction=new int[m+1];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				map[i][j]=sc.nextInt();//상어 번호있음
			}
		}
//		각 상어 초기 방향
		for (int i = 1; i <= m; i++) {
			direction[i]=sc.nextInt()-1;//0 1 2 3
		}
		
		//각 상어 우선순위
		for (int i = 1; i <= m; i++) {
			for (int p = 0; p < 4; p++) {
				for (int k = 0; k < 4; k++) {
					sharks[i][p][k]=sc.nextInt()-1;//방향 인덱스
				}
			}
		}
		
		int time=0;
		while(time<=1000) {	
			makeSmell();
			move();
			time++;
			if(total==m-1)break;
		}
		
		System.out.println(time>1000?-1:time);
	}
	private static void move() {
		
		int[][] copy=new int[n][n];
		
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if(map[i][j]!=0 && !isDead[map[i][j]]) {//아직 안 죽은 상어
					int num=map[i][j];
					int dir=direction[num];//현재 상어의 방향
					boolean check=false;
					int yy=0,xx=0;//이동할 곳
					for (int p = 0; p <4; p++) {
						
						int k= sharks[num][dir][p];//우선순위 방향
						yy=i+ypos[k];
						xx=j+xpos[k];
						if(yy<0 || xx<0 || xx>=n || yy>=n)continue;
						if(smell[yy][xx][0]==0) {//갈 곳 있음
							check=true;
							direction[num]=k;
							break;
						}
					}
					//갈 곳이 없었을 경우 자신의 번호 방향으로 간다. 되돌아감. 방향 반대로 전환해준다.
					if(check==false) {
						for (int p = 0; p <4; p++) {
							int k= sharks[num][dir][p];//우선순위 방향
							yy=i+ypos[k];
							xx=j+xpos[k];
							if(yy<0 || xx<0 || xx>=n || yy>=n)continue;
							if(smell[yy][xx][0]==num) {
								direction[num]=k;
								break;
							}
						}
						
					}
					
					if(copy[yy][xx]==0) {//아무도 없을 경우
						copy[yy][xx]=num;
					}else {//다른 상어가 먼저 있을 경우 
						if(copy[yy][xx]<num) {//나보다 작은 상어
							isDead[num]=true;
							total+=1;
						}else {
							isDead[copy[yy][xx]]=true;
							copy[yy][xx]=num;//내가 이겨따~
							total+=1;
						}
					}
				
					
				}
			}
		}
		
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				map[i][j]=copy[i][j];//새로운 상어의 위치
			}
		}

	}
	
	
	private static void makeSmell() {
		
		//기존의 냄새는 1줄인다.
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if(smell[i][j][0]!=0) {//냄새가 있는 곳
					smell[i][j][1]-=1;//시간 줄이기
					if(smell[i][j][1]==0) {//0이되면 상어 표시도 없애준다.
						smell[i][j][0]=0;
					}
				}
			}
		}
		
		// 새로운 냄새 만들기
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if(map[i][j]!=0) {
					int num=map[i][j];
					smell[i][j][0]=num;//상어 번호
					smell[i][j][1]=k;//시간
				}
			}
		}
		
		
	}
}
728x90
반응형
TAGS.

Comments