R * C의 격자판에서 낚시왕이 1초에 한 열씩 이동하며 땅과 가장 가까운 상어를 잡습니다. 상어를 잡으면 해당 좌표의 상어는 사라지고, 남은 상어가 이동합니다. 상어는 속력과 방향, 크기를 가지고 있으며 1초동안 속력만큼의 칸을 이동합니다. 상어의 이동 칸이 격자판을 넘는 경우 방향을 바꿔 반대방향으로 이동하면 됩니다.
최종 이동 후 같은 칸에 상어가 2마리가 존재하게 되면, 크기가 작은 상어는 잡아먹힙니다.
낚시왕의 이동 -> 낚시 -> 상어 이동
은 1초 동안 일어나게 되고, 최종적으로 낚시왕이 모든 열을 이동하면서 잡은 상어 크기의 합을 구하면 되는 문제입니다.
getShark()
r을 1씩 증가시키면서 map[r][c]의 값이 null이 아니면 상어를 잡습니다.moveShark()
상어가 이동합니다.eatShark()
map으로 상어를 한 마리씩 넣어주는데, map의 해당 좌표가 null이면 shark를 넣어주고, 아니라면 크기를 비교해서 넣어줍니다. 잡아먹힌 상어는 sharks 객체 배열에서도 삭제합니다.import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class BOJ_17143 {
static int r;
static int c;
static int shark_num;
static int total_size = 0;
static Shark[][] map;
static ArrayList<Shark> sharks = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
shark_num = Integer.parseInt(st.nextToken());
if (shark_num == 0) {
System.out.println(0);
return;
}
map = new Shark[r + 1][c + 1];
for (int i = 0; i < shark_num; i++) {
String input = br.readLine();
st = new StringTokenizer(input);
int r = Integer.parseInt(st.nextToken()); //x
int c = Integer.parseInt(st.nextToken()); //y
int s = Integer.parseInt(st.nextToken()); //속력
int d = Integer.parseInt(st.nextToken()); //방향
int z = Integer.parseInt(st.nextToken()); //크기
Shark shark = new Shark(r, c, z, s, d);
map[r][c] = shark;
sharks.add(shark);
}
for (int i = 1; i <= c; i++) {
getShark(i);
moveShark();
eatShark();
}
System.out.println(total_size);
}
static void getShark(int col) {
Shark temp = null;
for (int i = 1; i <= r; i++) {
if (map[i][col] != null) {
temp = map[i][col];
break;
}
}
if (temp != null) {
map[temp.x][temp.y] = null;
total_size += temp.size;
sharks.remove(temp);
}
}
static void moveShark() {
for (int i = 0; i < sharks.size(); i++) {
Shark shark = sharks.get(i);
map[shark.x][shark.y] = null;
shark.go();
}
}
static void eatShark() {
for (int i = sharks.size() - 1; i >= 0; i--) {
Shark s = sharks.get(i);
if (map[s.x][s.y] == null) {
map[s.x][s.y] = s;
} else {
if (map[s.x][s.y].size > s.size) {
sharks.remove(s);
} else {
sharks.remove(map[s.x][s.y]);
map[s.x][s.y] = s;
}
}
}
}
static class Shark {
int x;
int y;
int size;
int speed;
int direction;
public Shark(int x, int y, int size, int speed, int direction) {
this.x = x;
this.y = y;
this.size = size;
this.speed = speed;
this.direction = direction;
}
public void go() {
for (int i = 0; i < speed; i++) {
switch (this.direction) {
case 1: // 위
if (x == 1) {
x++;
this.direction = 2;
} else {
x--;
}
break;
case 2: //아래:
if (x == r) {
x--;
this.direction = 1;
} else {
x++;
}
break;
case 3: //오른쪽
if (y == c) {
y--;
this.direction = 4;
} else {
y++;
}
break;
case 4: //왼쪽:
if (y == 1) {
y++;
this.direction = 3;
} else {
y--;
}
break;
}
}
}
}
}
상어의 최종 이동을 하는데에 조금 오래 걸렸습니다. sharks 배열을 0부터 돌면 틀리고 거꾸로 돌리면 맞는데, 왜 맞는지 이해가 안 갑니다..
상어의 방향을 돌려주는 것을 case문으로 나눠서 풀었지만, 위 - 아래와 좌 - 우 이동을 묶어서 이동 거리를 계산하고 범위를 벗어나면 방향을 돌려주는 풀이도 있었습니다.