https://www.acmicpc.net/problem/20057
1. 아이디어
달팽이 배열처럼 이동하는 것은 이동 길이가 1, 1, 2, 2, 3 이렇게 1부터 수가 두 번 등장하면 방향이 바뀌는 것을 이용했고, 모래의 이동은 5 x 5의 배열에 미리 이동시킨 후 대조하는 방식으로 해결했다.
2. 문제풀이
모래가 흩날린 경우의 이동을 2차원 배열로 바꾼 후 원본 배열과 인덱스 비교를 통해 이동시키는 방식을 적용했다. 토네이토 소멸 후 격자 내의 모래의 합을 구해서 이를 최초 값과 비교하는 방식으로 격자 밖으로 나간 모래의 양을 구했다.
3. 코드
import java.io.*;
import java.util.*;
public class Main {
private static final int[] dr = {0, 1, 0, -1};
private static final int[] dc = {-1, 0, 1, 0};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int sum = 0;
int[][] map = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
sum += map[i][j];
}
}
int r = N / 2;
int c = N / 2;
int d = 0;
int len = 1;
int check = 0;
int cnt = 0;
while (true) {
r += dr[d];
c += dc[d];
if (c < 0) break;
spread(r, c, d, N, map);
cnt++;
if (len == cnt) {
d = (d + 1) % 4;
check++;
cnt = 0;
}
if (check == 2) {
len++;
check = 0;
}
}
int exist = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
exist += map[i][j];
}
}
System.out.println(sum - exist);
}
private static void spread(int r, int c, int d, int N, int[][] map) {
int[][] matrix = getMatrix(map[r][c], d);
for (int i = r - 2; i <= r + 2; i++) {
for (int j = c - 2; j <= c + 2; j++) {
if (i < 0 || i >= N || j < 0 || j >= N) continue;
map[i][j] += matrix[i - r + 2][j - c + 2];
}
}
map[r][c] = 0;
}
private static int[][] getMatrix(int sand, int d) {
int one = sand / 100;
int two = sand / 50;
int five = sand / 20;
int seven = sand * 7 / 100;
int ten = sand / 10;
int remain = sand - 2 * one - 2 * two - 2 * seven - 2 * ten - five;
if (d == 0) return new int[][]{
{0, 0, two, 0, 0},
{0, ten, seven, one, 0},
{five, remain, 0, 0, 0},
{0, ten, seven, one, 0},
{0, 0, two, 0, 0},
};
if (d == 1) return new int[][]{
{0, 0, 0, 0, 0},
{0, one, 0, one, 0},
{two, seven, 0, seven, two},
{0, ten, remain, ten, 0},
{0, 0, five, 0, 0},
};
if (d == 2) return new int[][]{
{0, 0, two, 0, 0},
{0, one, seven, ten, 0},
{0, 0, 0, remain, five},
{0, one, seven, ten, 0},
{0, 0, two, 0, 0},
};
return new int[][]{
{0, 0, five, 0, 0},
{0, ten, remain, ten, 0},
{two, seven, 0, seven, two},
{0, one, 0, one, 0},
{0, 0, 0, 0, 0},
};
}
}
4. 후기
'코딩테스트 준비 > 백준' 카테고리의 다른 글
[백준] 2257번 - 화학식량 [Java] (0) | 2025.02.18 |
---|---|
[백준] 8979번 - 올림픽 [Java] (0) | 2025.02.18 |
[백준] 33165번 - 徒競走 (Footrace) [Java] (0) | 2025.02.17 |
[백준] 13277번 - 큰 수 곱셈 [Java] (0) | 2025.02.17 |
[백준] 1966번 - 프린터 큐 [Java] (1) | 2025.02.15 |