티스토리 뷰
https://www.acmicpc.net/problem/20057
🐢 설명
- 모래가 정사각형 공간에 존재한다.
- 토네이도는 반시계 방향으로 정가운데에서 불기 시작한다. 이때 방향은 <-, ㅜ, ->, ㅗ 순서이다.
- 바람이 불면 해당 방향 바로 앞 좌표에 존재하는 모래가 이동한다.
- (3, 3)에서 바람이 왼쪽으로 불면, (3, 2)의 모래가 이동한다.
- 모래가 이동하면 문제에서 나오는데로 모래가 먼저 다 퍼진다. 이때 0이하의 모래는 무시한다.
- 기존 모래 - 실제로 퍼진 모래만이 a부분으로 이동한다.
- 이때 기존 모래는 0이 된다.
이동거리가 m일 때 총 2회씩 이동하고 m의 길이가 1 증가한다. 또한 m이 총 공간의 길이 - 1에 도달할 경우 3회 이동을 하고 종료된다.
토네이도가 왼쪽으로 이동할 때 모래가 이동하는 경우와 위로 이동할 때 이동하는 경우를 만들어주고, 반대의 경우는 방향만 변경하도록 했다. 이때 범위체크를 해서 벗어나면 벗어난 모래양에 더해주고, 그렇지 않다면 기존 모래사장에 더해주도록 했다.
🐢코드
public class 마법사상어와토네이도_20057 {
static int[] dy = {0, 1, 0, -1};
static int[] dx = {-1, 0, 1, 0};
static int N;
static int[][] sandBox;
static int outSand;
public static void main(String[] args) throws IOException {
input();
solve();
}
private static void solve() {
// torado left, down, right, up
Pair start = new Pair(N / 2, N / 2);
int move = 1;
int turnCnt = 2;
int dir = 0;
while (move < N) {
if (move == N - 1) {
turnCnt = 3;
}
for (int cnt = 0; cnt < turnCnt; cnt++) {
for (int go = 0; go < move; go++) {
start.first += dy[dir];
start.second += dx[dir];
moveSand(start.first, start.second, dir);
}
++dir;
dir %= 4;
}
++move;
}
System.out.println(outSand);
}
private static void moveSand(int y, int x, int dir) {
int initSize = sandBox[y][x];
int tenPercent = initSize * 10 / 100;
int sevenPercent = initSize * 7 / 100;
int fivePercent = initSize * 5 / 100;
int twoPercent = initSize * 2 / 100;
int onePercent = initSize / 100;
int alpha = initSize - (tenPercent * 2 + sevenPercent * 2 + onePercent * 2 + twoPercent * 2 + fivePercent);
sandBox[y][x] = 0;
/*
go left, right
*/
if (dir == 0 || dir == 2) {
int turn = 1;
if (dir == 2) turn = -1;
inBound(y, x - (turn * 2), fivePercent);
inBound(y, x - turn, alpha);
inBound(y - 1, x - turn, tenPercent);
inBound(y - 1, x, sevenPercent);
inBound(y - 1, x + turn, onePercent);
inBound(y + 1, x - turn, tenPercent);
inBound(y + 1, x, sevenPercent);
inBound(y + 1, x + turn, onePercent);
inBound(y - 2, x, twoPercent);
inBound(y + 2, x, twoPercent);
}
/*
go down, up
*/
if (dir == 1 || dir == 3) {
int turn = 1;
if (dir == 1) turn = -1;
inBound(y - turn * 2, x, fivePercent);
inBound(y - turn, x, alpha);
inBound(y - turn, x + 1, tenPercent);
inBound(y, x + 1, sevenPercent);
inBound(y + turn, x + 1, onePercent);
inBound(y - turn, x - 1, tenPercent);
inBound(y, x - 1, sevenPercent);
inBound(y + turn, x - 1, onePercent);
inBound(y, x - 2, twoPercent);
inBound(y, x + 2, twoPercent);
}
}
private static void inBound(int y, int x, int plusSand) {
if (y >= 0 && y < N && x >= 0 && x < N) {
sandBox[y][x] += plusSand;
} else {
outSand += plusSand;
}
}
private static void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
sandBox = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
sandBox[i][j] = Integer.parseInt(st.nextToken());
}
}
}
private static class Pair {
int first;
int second;
public Pair(int first, int second) {
this.first = first;
this.second = second;
}
}
}
🐢 마무리
반응형
'알고리즘 > 백준' 카테고리의 다른 글
(백준) 뱀 _ 3190 (0) | 2021.10.22 |
---|---|
(백준) 마법사 상어와 파이어스톰 (0) | 2021.10.19 |
(백준) 독서실 거리두기 _ 20665 (0) | 2021.10.10 |
(백준) 사과와 바나나 _ 3114 (0) | 2021.09.29 |
(백준) 컬러볼 - 10800 (0) | 2021.09.16 |
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday