낚시왕 문제는 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("================================");
}
}
PREVIOUS[Spring] DI 와 IoC Container