반응형
문제
https://www.acmicpc.net/problem/21610
JAVA코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
private static int N, M;
private static int[][] map;
private static boolean[][] visited;
// 0, 1, 2, 3, 4, 5, 6, 7, 8
// 공백, ←, ↖, ↑, ↗, →, ↘, ↓, ↙
private static int[] dy = { 0, 0, -1, -1, -1, 0, 1, 1, 1 };
private static int[] dx = { 0, -1, -1, 0, 1, 1, 1, 0, -1 };
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N + 1][N + 1];
visited = new boolean[N + 1][N + 1];
for (int row = 1; row <= N; row++) {
st = new StringTokenizer(br.readLine());
for (int col = 1; col <= N; col++) {
map[row][col] = Integer.parseInt(st.nextToken());
}
}
int di = 0;
int si = 0;
List<Cloud> clouds = new ArrayList<>();
// 비바라기를 시전하면 (N, 1), (N, 2), (N-1, 1), (N-1, 2)에 비구름이 생긴다.
clouds.add(new Cloud(N, 1));
clouds.add(new Cloud(N, 2));
clouds.add(new Cloud(N - 1, 1));
clouds.add(new Cloud(N - 1, 2));
for (int idx = 1; idx <= M; idx++) {
st = new StringTokenizer(br.readLine());
di = Integer.parseInt(st.nextToken());
si = Integer.parseInt(st.nextToken());
// init cloud visited
for (int row = 1; row <= N; row++) {
for (int col = 1; col <= N; col++) {
visited[row][col] = false;
}
}
for (Cloud cloud : clouds) {
// 1. 모든 구름이 di 방향으로 si칸 이동한다.
cloud.setRow(convertPos(((cloud.getRow() + (si * dy[di])) % N)));
cloud.setCol(convertPos(((cloud.getCol() + (si * dx[di])) % N)));
// 2. 각 구름에서 비가 내려 구름이 있는 칸의 바구니에 저장된 물의 양이 1 증가한다.
map[cloud.getRow()][cloud.getCol()] += 1;
// 3. 기존 구름의 위치 기록
visited[cloud.getRow()][cloud.getCol()] = true;
}
for (Cloud cloud : clouds) {
// 4. 2에서 물이 증가한 칸 (r, c)에 물복사버그 마법을 시전한다. 물복사버그 마법을 사용하면,
// 대각선 방향으로 거리가 1인 칸에 물이 있는 바구니의 수만큼 (r, c)에 있는 바구니의 물이 양이 증가한다.
for (int cross = 2; cross <= 8; cross = cross + 2) {
// 4-1. 이때는 이동과 다르게 경계를 넘어가는 칸은 대각선 방향으로 거리가 1인 칸이 아니다.
// 4-2. 예를 들어, (N, 2)에서 인접한 대각선 칸은 (N-1, 1), (N-1, 3)이고,
// (N, N)에서 인접한 대각선 칸은 (N-1, N-1)뿐이다.
if (!isValid(cloud.getRow() + dy[cross], cloud.getCol() + dx[cross]))
continue;
if (map[cloud.getRow() + dy[cross]][cloud.getCol() + dx[cross]] != 0) {
map[cloud.getRow()][cloud.getCol()] += 1;
}
}
}
// 3. 구름이 모두 사라진다.
clouds.clear();
;
// 5. 바구니에 저장된 물의 양이 2 이상인 모든 칸에 구름이 생기고, 물의 양이 2 줄어든다.
// 이때 구름이 생기는 칸은 3에서 구름이 사라진 칸이 아니어야 한다.
for (int row = 1; row <= N; row++) {
for (int col = 1; col <= N; col++) {
if ((map[row][col] >= 2) && !visited[row][col]) {
map[row][col] -= 2;
clouds.add(new Cloud(row, col));
}
}
}
// System.out.println();
// System.out.println("M: " + idx);
// for (int row = 1; row <= N; row++) {
// for (int col = 1; col <= N; col++) {
// System.out.print(map[row][col] + " ");
// }
// System.out.println();
// }
}
// M번의 이동이 모두 끝난 후 바구니에 들어있는 물의 양의 합을 구해보자.
int result = 0;
for (int row = 1; row <= N; row++) {
for (int col = 1; col <= N; col++) {
result += map[row][col];
}
}
System.out.println(result);
br.close();
}
// 격자의 가장 왼쪽 윗 칸은 (1, 1)이고, 가장 오른쪽 아랫 칸은 (N, N)이다.
// 마법사 상어는 연습을 위해 1번 행과 N번 행을 연결했고, 1번 열과 N번 열도 연결했다.
// 즉, N번 행의 아래에는 1번 행이, 1번 행의 위에는 N번 행이 있고,
// 1번 열의 왼쪽에는 N번 열이, N번 열의 오른쪽에는 1번 열이 있다.
public static int convertPos(int pos) {
if (pos < 1)
return (N + pos) == 0 ? N : (N + pos);
return pos;
}
public static boolean isValid(int row, int col) {
if (row < 1 || col < 1 || row > N || col > N)
return false;
return true;
}
public static class Cloud {
int row;
int col;
public Cloud(int row, int col) {
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
public void setRow(int row) {
this.row = row;
}
public void setCol(int col) {
this.col = col;
}
}
}
반응형
'Algorithm > 문제 풀이' 카테고리의 다른 글
[BAEKJOON_1316 - JAVA] 그룹 단어 체커 (0) | 2023.07.10 |
---|---|
[BAEKJOON_2531 - JAVA] 회전 초밥 (0) | 2023.06.22 |
[BAEKJOON_19637 - JAVA] IF문 좀 대신 써줘 (0) | 2023.06.17 |
[BAEKJOON_1446 - JAVA] 지름길 (0) | 2023.06.16 |
[BAEKJOON_14503 -JAVA] 로봇 청소기 (0) | 2023.06.16 |