No Rules Rules

마법사 상어와 비바라기 (feat. 백준, 21610번) 본문

생활/코테

마법사 상어와 비바라기 (feat. 백준, 21610번)

개발하는 완두콩 2022. 7. 27. 22:36
728x90
반응형

마법사 상어와 비바라기
https://www.acmicpc.net/problem/21610

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net

반응형
// woohyeon.kim
// https://www.acmicpc.net/problem/21610
#include <iostream>
using namespace std;
int N, M, arr[51][51], cloud[51][51], d, dx[8], dy[8];
inline void make_cloud() {
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			cloud[ix][iy] = 0;
	cloud[N][1] = cloud[N][2] = cloud[N - 1][1] = cloud[N - 1][2] = 1;
}
inline void move_cloud(const int& d, const int& s) {
	int tmp[51][51] = { 0 };
	for(int ix = 1, iy, nx, ny; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy) {
			if (cloud[ix][iy]) {
				nx = ix + dx[d] * s, ny = iy + dy[d] * s;
				while (nx > N)		nx -= N;
				while (nx <= 0)		nx += N;
				while (ny > N)		ny -= N;
				while (ny <= 0)		ny += N;
				tmp[nx][ny] = 1;
			}
		}
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			cloud[ix][iy] = tmp[ix][iy];
}
inline void its_raining() {
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			if (cloud[ix][iy])
				++arr[ix][iy];
}
inline void compare_cross() {
	for(int ix = 1, iy, i, nx, ny; ix <= N; ++ix)
		for(iy = 1; iy <= N; ++iy)
			if (cloud[ix][iy])
				for (i = 0; i < 4; ++i) {
					nx = ix + dx[i * 2 + 1], ny = iy + dy[i * 2 + 1];
					if (1 <= nx && nx <= N && 1 <= ny && ny <= N && arr[nx][ny])
						++arr[ix][iy];
				}
}
inline void decrese_water() {
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			if (cloud[ix][iy])
				cloud[ix][iy] = 0;
			else
				if (arr[ix][iy] >= 2)		cloud[ix][iy] = 1, arr[ix][iy] -= 2;
}
int main() {
	ios::sync_with_stdio(false), cin.tie(), cout.tie();
	dx[0] = dx[4] = 0, dx[1] = dx[2] = dx[3] = -1, dx[5] = dx[6] = dx[7] = 1;
	dy[2] = dy[6] = 0, dy[0] = dy[1] = dy[7] = -1, dy[3] = dy[4] = dy[5] = 1;
	cin >> N >> M;
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			cin >> arr[ix][iy];
	make_cloud();
	for (int m = 0, d, s; m < M; ++m) {
		cin >> d >> s;
		move_cloud(d - 1, s);
		its_raining();
		compare_cross();
		decrese_water();
	}
	auto result = 0;
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			result += arr[ix][iy];
	cout << result << endl;
	return 0;
}
// *&)*@*
  1. 가장 처음의 구름은 (N,1) (N,2) (N-1,1) (N-1,2) 에서 발생합니다.
  2. 그 뒤부터는 문제에서 주어진 조건 중 5번의 조건에 의해 생긴 구름이 1번에서 적용되어야 합니다.
728x90
반응형
Comments