[삼성기출]백준17143 - 낚시왕

 
by 박신종

낚시왕 문제는 2019 상반기 공채 문제로, 일반 구현 문제이다.

문제풀기 - [백준17143 낚시왕]


상어에 대한 정보를 2차 배열에 넣고, 상태변이로 문제를 풀었으며,

각 상어의 속도 시간을 S(속도) % (Depth or Width - 1)*2 식으로 단축 시킬 수 있다.


import java.io.*;
import java.util.*;

public class Main17143_낚시왕 {
	static int R,C,M;
	static int[][] dir = {{0,0},{-1,0},{1,0},{0,1},{0,-1}}; // 0,1위,2아래,3오른,4왼
	static int[][] map, sharks;
	static boolean check(int x, int y) {
		if(x>=0 && x<map.length && y>=0 && y<map[x].length)
			return true;
		else return false;
	}
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().trim().split(" ");
		R = Integer.parseInt(input[0]); // 0번째 줄은 낚시왕
		C = Integer.parseInt(input[1]);
		M = Integer.parseInt(input[2])+1; // 0번은 없음
		
		map = new int[R][C];
		sharks = new int[M][6]; // 상어는 1번부터 ~
		String[] shark = null;
		for(int i=1; i<M; i++) {
			shark = br.readLine().trim().split(" ");
			for(int j=0; j<5; j++) {
				if(j==0 || j==1) sharks[i][j] = Integer.parseInt(shark[j])-1; 
				else sharks[i][j] = Integer.parseInt(shark[j]);
			}
			map[sharks[i][0]][sharks[i][1]] = i;
		}
		
		for(int y=0; y<C; y++) {
			catchShark(y);
			moveShark();
		}
		System.out.println(res);
	}
	
	/*
	 * 상어가 정해진 상태값으로 움직이고, 먹히는 함수.
	 */
	static void moveShark() {
		clear();
		//0:x, 1:y, 2:s(속력), 3:d(방향), 4:z(크기), 5:c(catch)
		int x,y,s,d,z;
		for(int i=1; i<sharks.length; i++) {
			if(sharks[i][5] == -1) continue;
			x = sharks[i][0];
			y = sharks[i][1];
			s = sharks[i][2];
			d = sharks[i][3];
			z = sharks[i][4];
			
			if(d==1 || d==2) {
				s %= 2*(R-1);	// 최적화: 길이의 2배로 나눠주면 좌표와 방향이 원위치, 나머지만 계산해주면됨
				while(s>0) {
					if(x==0) d=2;
					else if(x==R-1) d=1;
					x+=dir[d][0];
					s--;
				}
			}else {
				s %= 2*(C-1);
				while(s>0) {
					if(y==0) d=3;
					else if(y==C-1) d=4;
					y+=dir[d][1];
					s--;
				}
			}
			
			/*
			 * 변경된 좌표와 방향 저장.
			 */
			sharks[i][0] = x;
			sharks[i][1] = y;
			sharks[i][3] = d;
			/*
			 * 이동된 상어들에서 한칸에 크기가 가장 큰 상어만 올 수 있음.
			 */
			if(map[x][y] == 0) map[x][y] = i; // 빈자리면 등록.
			else {
				if(sharks[map[x][y]][4] < z) { 	// 이미 상어가 존재하고, 지금 이동된 상어가 더 크면,
					sharks[map[x][y]][5]=-1;	// 이미 존재하는 상어는 죽어.
					map[x][y]=i;				// 그 자리에 현재 상어 위치. 
				}else {
					sharks[i][5]=-1;			// 이미 상어가 존재하고, 그 상어가 더크면, 지금상어는 죽어
				}
			}
			
		}
		
	}
	
	static int res;
	/*
	 * 낚시왕이 가장 가까운 상어를 잡는 함수.
	 */
	static void catchShark(int y) {
		for(int x=0; x<R; x++) {
			if(map[x][y]!=0) {
				sharks[map[x][y]][5] = -1; // 잡았을 때 -1, 안잡혔을때 0
				res+=sharks[map[x][y]][4];
				map[x][y]=0;
				return;
			}
		}
		
	}
	static void clear() {
		for(int i=0; i<R; i++) {
			Arrays.fill(map[i], 0);
		}
	}
	static void print() {
		for(int i=0; i<R; i++) {
			for(int j=0; j<C; j++) {
				System.out.print(map[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println("================================");
	}
}