[백준] 마법사 상어와 파이어볼

2 minute read

문제 설명

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

제한사항

첫째 줄에 N, M, K가 주어진다.

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

서로 다른 두 파이어볼의 위치가 같은 경우는 입력으로 주어지지 않는다.


풀이

75분
잘한 점: 풀이를 끝까지 생각해낼 때 까지 키보드를 잡지 않았다.
못한 점: 문제에서 파이어볼이 사라지는(즉, 질량이 0이 되는) 경우를 제외하려고 조건문에 탈출문을 쓰는 실수를 했다. 탈출문을 써서 해당 행의 나머지 공간은 탐색하지 못하는 오류가 발생했다.

if ((int)(m_sum / 5) == 0) continue;

코드

// 04:04 ~ 05:19
//#pragma warning (disable:4996)
#include<iostream>
#include<vector>
using namespace std;

int dx[8] = { -1,-1,0,1,1,1,0,-1 };
int dy[8] = { 0,1,1,1,0,-1,-1,-1 };

struct fireball {
	int x, y, m, s, dir;
};

int main()
{
	// freopen("input.txt", "r", stdin);
	int n, m, k;
	int visit[50][50] = { 0, };
	int sum = 0;
	vector<fireball> now;
	vector<fireball> next;

	cin >> n >> m >> k;
	for (int i = 0; i < m; ++i) {
		fireball temp;
		cin >> temp.x >> temp.y >> temp.m >> temp.s >> temp.dir;
		--temp.x;
		--temp.y;
		now.push_back(temp);
	}

	while (k > 0) {

		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < n; ++j) {
				visit[i][j] = 0;
			}
		}

		for (int i = 0; i < now.size(); ++i) {
			now[i].x = (now[i].x + 1000 * n + now[i].s * dx[now[i].dir]) % n;
			now[i].y = (now[i].y + 1000 * n + now[i].s * dy[now[i].dir]) % n;
			visit[now[i].x][now[i].y]++;
		}

		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < n; ++j) {
				if (visit[i][j] >= 2) {
					int m_sum = 0;
					vector<int> dirs;
					int s_sum = 0;
					for (int k = 0; k < now.size(); ++k) {
						if (now[k].x == i && now[k].y == j) {
							m_sum += now[k].m;
							dirs.push_back(now[k].dir);
							s_sum += now[k].s;
							now.erase(now.begin() + k);
							--k;
						}
					}

					if ((int)(m_sum / 5) == 0) continue;

					fireball temp;
					int d = 0;

					for (int k = 0; k < dirs.size() - 1; ++k) {
						if ((dirs[k] + dirs[k + 1]) % 2 != 0) {
							d = 1;
							break;
						}
					}

					temp.x = i;
					temp.y = j;
					temp.m = m_sum / 5;
					temp.s = s_sum / visit[i][j];

					for (d; d <= 7; d += 2) {
						temp.dir = d;
						next.push_back(temp);
					}
				}
			}
		}

		for (int i = 0; i < next.size(); ++i) {
			now.push_back(next[i]);
		}

		next.clear();
		--k;
	}

	for (int i = 0; i < now.size(); ++i) {
		sum += now[i].m;
	}

	cout << sum;

	return 0;
}