와이유스토리

[시뮬레이션(회전)] (CHECK) 백준 20057 마법사 상어와 토네이도 C++ 본문

코딩테스트/시뮬레이션

[시뮬레이션(회전)] (CHECK) 백준 20057 마법사 상어와 토네이도 C++

유(YOO) 2023. 3. 31. 12:03

 

https://www.acmicpc.net/problem/20057

 

20057번: 마법사 상어와 토네이도

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

#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;
}
Comments