코딩테스트/시뮬레이션
[시뮬레이션(회전)] (CHECK) 백준 20057 마법사 상어와 토네이도 C++
유(YOO)
2023. 3. 31. 12:03
https://www.acmicpc.net/problem/20057
#include <iostream>
using namespace std;
int n;
int A[500][500];
float wind[4][5][5] = { { {0, 0, 0.02, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0.05, 0, 0, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0, 0, 0.02, 0, 0} } , { {0, 0, 0.02, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0.05, 0.75, 0, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0, 0, 0.02, 0, 0} } , { {0, 0, 0.02, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0.05, 0.75, 0, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0, 0, 0.02, 0, 0} } , { {0, 0, 0.02, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0.05, 0.75, 0, 0, 0}, {0, 0.1, 0.07, 0.01, 0}, {0, 0, 0.02, 0, 0} } };
int dx[4] = { -1, 0, 1, 0 }; // 좌하우상
int dy[4] = { 0, 1, 0, -1 };
void rotate() { // 반시계 회전
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) wind[1][i][j] = wind[0][j][4-i]; // 왼쪽 90도 회전
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) wind[2][i][j] = wind[0][4-i][4-j]; // 180도 회전
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) wind[3][i][j] = wind[0][4-j][i]; // 오른쪽 90도 회전
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(); cout.tie();
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) cin >> A[i][j];
}
rotate();
int cursorX = n / 2; // 현재 위치
int cursorY = n / 2;
int sand = 0; // 현재 위치 모래 양
int count = 1; // 위치 이동 칸 수
int answer = 0; // 격자 바깥 모래 양
while (true) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < count; j++) {
cursorX = cursorX + dx[i];
cursorY = cursorY + dy[i];
sand = A[cursorY][cursorX];
// 모래 이동
for (int p = cursorY - 2; p <= cursorY + 2; p++) {
for (int q = cursorX - 2; q <= cursorX + 2; q++) {
int blow = sand * wind[i][p - (cursorY - 2)][q - (cursorX - 2)];
A[cursorY][cursorX] -= blow;
if ((p < 0) || (q < 0) || (p >= n) || (q >= n)) answer += blow; // 격자 바깥
else A[p][q] += blow;
}
}
// 알파
int aX = cursorX + dx[i];
int aY = cursorY + dy[i];
if ((aX < 0) || (aY < 0) || (aX >= n) || (aY >= n)) answer += A[cursorY][cursorX]; // 격자 바깥
else A[aY][aX] += A[cursorY][cursorX];
A[cursorY][cursorX] = 0;
// 토네이도 소멸
if ((cursorX == 0) && (cursorY == 0)) {
cout << answer;
return 0;
}
}
if ((i == 1) || (i == 3)) count++;
}
}
return 0;
}