OJ
[BOJ] 21610 마법사 상어와 비바라기 (JAVA)
P3PP4
2023. 3. 12. 10:00
https://www.acmicpc.net/problem/21610
21610번: 마법사 상어와 비바라기
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기
www.acmicpc.net
구현은 재밌는데 귀찮아요
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int N, M, d, s, result;
static int[][] A;
static int[] dr = { 0, -1, -1, -1, 0, 1, 1, 1 };
static int[] dc = { -1, -1, 0, 1, 1, 1, 0, -1 };
static boolean[][] check;
static ArrayList<int[]> list = new ArrayList<>();
static ArrayList<int[]> clouds = new ArrayList<>();
public static void main(String[] args) throws Exception {
st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
A = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < N; j++) {
A[i][j] = Integer.parseInt(st.nextToken());
}
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
d = Integer.parseInt(st.nextToken()) - 1;
s = Integer.parseInt(st.nextToken()) % N;
list.add(new int[] { d, s });
} // end of input
// 첫 구름들
clouds.add(new int[] { N - 2, 0 });
clouds.add(new int[] { N - 2, 1 });
clouds.add(new int[] { N - 1, 0 });
clouds.add(new int[] { N - 1, 1 });
for (int num = 0; num < M; num++) {
int[] skill = list.get(num);
// 이동
for (int i = 0; i < clouds.size(); i++) {
int[] cloud = clouds.get(i);
for (int j = 0; j < skill[1]; j++) {
cloud[0] += dr[skill[0]];
cloud[1] += dc[skill[0]];
cloud[0] = cloud[0] < 0 ? cloud[0] + N : cloud[0] % N;
cloud[1] = cloud[1] < 0 ? cloud[1] + N : cloud[1] % N;
}
clouds.set(i, cloud);
}
// 구름 있는 칸에 비 1씩 내림
for (int[] cloud : clouds) {
A[cloud[0]][cloud[1]]++;
}
// 대각선 물 흡수
int[] w = new int[clouds.size()];
for (int i = 0; i < clouds.size(); i++) {
int[] cloud = clouds.get(i);
for (int dir = 1; dir < 8; dir += 2) {
int nr = cloud[0] + dr[dir];
int nc = cloud[1] + dc[dir];
if (0 <= nr && nr < N && 0 <= nc && nc < N && 0 < A[nr][nc]) w[i]++;
}
}
for (int i = 0; i < clouds.size(); i++) {
int[] cloud = clouds.get(i);
A[cloud[0]][cloud[1]] += w[i];
}
// 구름 생기고 물 제거
check = new boolean[N][N];
for (int[] cloud : clouds) {
check[cloud[0]][cloud[1]] = true;
}
clouds.clear();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!check[i][j] && 2 <= A[i][j]) {
clouds.add(new int[] { i, j });
A[i][j] -= 2;
}
}
}
}
// 남아있는 물 셈
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
result += A[i][j];
}
}
System.out.print(result);
}
}