No Rules Rules

마법사 상어와 파이어볼 (feat. 백준, 20056번) 본문

생활/코테

마법사 상어와 파이어볼 (feat. 백준, 20056번)

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

마법사 상어와 파이어볼
https://www.acmicpc.net/problem/20056

 

20056번: 마법사 상어와 파이어볼

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치

www.acmicpc.net

반응형
// woohyeon.kim
// https://www.acmicpc.net/problem/20056
#include <iostream>
#include <queue>
using namespace std;
struct Fireball {
	int x, y, m, d, s;
};
int N, M, K, dx[8], dy[8];
inline void move_fireball(queue<Fireball> (*fireballs)[51]) {
	register queue<Fireball> fireball_tmp;
	for(register int ix = 1, iy, nx, ny; ix <= N; ++ix)
		for(iy = 1; iy <= N; ++iy)
			while (!fireballs[ix][iy].empty()) {
				auto& fireball = fireballs[ix][iy].front();
				nx = ix + dx[fireball.d] * fireball.s, ny = iy + dy[fireball.d] * fireball.s;
				if (nx < 1)			while (nx < 1)		nx += N;
				else if (nx > N)	while (nx > N)		nx -= N;
				if (ny < 1)			while (ny < 1)		ny += N;
				else if (ny > N)	while (ny > N)		ny -= N;
				fireball.x = nx, fireball.y = ny, fireball_tmp.push(fireball);
				fireballs[ix][iy].pop();
			}
	while (!fireball_tmp.empty()) {
		auto& fireball = fireball_tmp.front();
		fireballs[fireball.x][fireball.y].push(fireball);
		fireball_tmp.pop();
	}
}
inline void changed_fireball(queue<Fireball>(*fireballs)[51]) {
	for (register int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			if (fireballs[ix][iy].size() >= 2) {
				register int fireball_count = static_cast<int>(fireballs[ix][iy].size());
				register Fireball fireball{ ix, iy, 0, 0, 0 };
				register bool odd = false, even = false;
				while (!fireballs[ix][iy].empty()) {
					auto& fireball_tmp = fireballs[ix][iy].front();
					fireball.m += fireball_tmp.m;
					fireball.s += fireball_tmp.s;
					if (fireball_tmp.d & 1)			odd = true;
					else							even = true;
					fireballs[ix][iy].pop();
				}
				if ((fireball.m /= 5) == 0)
					continue;
				fireball.s /= fireball_count;
				if (even && odd) {
					fireball.d = 1, fireballs[ix][iy].push(fireball);
					fireball.d = 3, fireballs[ix][iy].push(fireball);
					fireball.d = 5, fireballs[ix][iy].push(fireball);
					fireball.d = 7, fireballs[ix][iy].push(fireball);
				}
				else {
					fireball.d = 0, fireballs[ix][iy].push(fireball);
					fireball.d = 2, fireballs[ix][iy].push(fireball);
					fireball.d = 4, fireballs[ix][iy].push(fireball);
					fireball.d = 6, fireballs[ix][iy].push(fireball);
				}
			}
}
inline void check(queue<Fireball>(*fireballs)[51]) {
	register int m = 0;
	for (register int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= N; ++iy)
			while (!fireballs[ix][iy].empty())
				m += fireballs[ix][iy].front().m, fireballs[ix][iy].pop();
	cout << m << endl;
}
int main() {
	ios::sync_with_stdio(false), cin.tie(), cout.tie();
	dx[7] = dx[0] = dx[1] = -1, dx[6] = dx[2] = 0, dx[5] = dx[4] = dx[3] = 1;
	dy[7] = dy[6] = dy[5] = -1, dy[0] = dy[4] = 0, dy[1] = dy[2] = dy[3] = 1;
	cin >> N >> M >> K;
	register Fireball fireball;
	register queue<Fireball> fireballs[51][51];
	for (register int m = 0; m < M; ++m) {
		cin >> fireball.x >> fireball.y >> fireball.m >> fireball.s >> fireball.d;
		fireballs[fireball.x][fireball.y].push(fireball);
	}
	for (register int k = 0; k < K; ++k) {
		move_fireball(fireballs);
		changed_fireball(fireballs);
	}
	check(fireballs);
	return 0;
}
// *&)*@*
  1. 문제에서 1번행과 N번행이, 1번열과 N번열이 연결되어 있다는 것은 방향에 의해 파이어볼이 이동할때 1->N으로 갈수 있다는 것을 의미합니다.
  2. 2번의 조건에서 파이어볼이 4개로 나눠지고 3번에 의해 각각의 파이어볼에 정보가 담기게 됩니다. 이 파이어볼들이 움직이는 시점은 다음번 K 입니다.
728x90
반응형
Comments