문제
- N*N 개의 칸이 주어집니다.
- M개의 파이어볼이 있습니다.
- 파이어볼은 상하좌우, 대각선을 포함해서 인접한 8개의 칸으로 움질 일 수 있습니다.
- 모든 파이어볼이 자신의 방향 d로 속력 s만큼 이동합니다.
- N(4 ≤ N ≤ 50) 지도의 크기
- M(5 ≤ M ≤ N^2) 파이어볼의 개수
- K(1 ≤ K ≤ 1000) 마법사 명령의 횟수
- 시간 제한 1초
- 문제 링크
#include <iostream>
#include <vector>
#include <queue>
#define max_int 51
using namespace std;
int N, M, K, r, c, m, s, d, result;
int dx[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
int dy[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
int abs(int num) {
return num < 0 ? num * -1 : num;
}
struct fireball {
int m, s, d;
};
queue<fireball> base[max_int][max_int];
struct info {
int cnt, mass, speed, direction;
bool is_odd, is_even;
};
info sum_info[max_int][max_int];
void clear_sum_info() {
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= N; j++) {
sum_info[i][j] = {0, 0, 0, 0, true, true};
}
}
}
void move_fire_ball() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
while (!base[i][j].empty()) {
fireball cur = base[i][j].front();
base[i][j].pop();
int nx = i + dx[cur.d] * cur.s;
int ny = j + dy[cur.d] * cur.s;
if (nx < 1 || nx > N || ny < 1 || ny > N) {
if (nx < 1) nx = (abs(nx) % N) * -1 + N;
if (ny < 1) ny = (abs(ny) % N) * -1 + N;
if (nx > N) nx = nx % N == 0 ? N : nx % N;
if (ny > N) ny = ny % N == 0 ? N : ny % N;
}
sum_info[nx][ny].cnt++;
sum_info[nx][ny].mass += cur.m;
sum_info[nx][ny].speed += cur.s;
sum_info[nx][ny].direction += cur.d;
if (cur.d % 2 == 0) sum_info[nx][ny].is_odd = false;
if (cur.d % 2 == 1) sum_info[nx][ny].is_even = false;
}
}
}
}
void split_fire_ball() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (sum_info[i][j].cnt <= 0) continue;
if (sum_info[i][j].cnt == 1) {
result += sum_info[i][j].mass;
base[i][j].push({ sum_info[i][j].mass, sum_info[i][j].speed, sum_info[i][j].direction });
continue;
}
int mass = sum_info[i][j].mass / 5;
int speed = sum_info[i][j].speed / sum_info[i][j].cnt;
if (mass <= 0) continue;
int start_idx = 1;
if (sum_info[i][j].is_odd || sum_info[i][j].is_even) start_idx = 0;
for (int idx = start_idx; idx < 8; idx += 2) {
base[i][j].push({ mass, speed, idx });
result += mass;
}
}
}
}
int main() {
scanf("%d %d %d", &N, &M, &K);
for (int i = 1; i <= M; i++) {
scanf("%d %d %d %d %d", &r, &c, &m, &s, &d);
base[r][c].push({ m, s, d });
}
while (K--) {
result = 0;
clear_sum_info();
move_fire_ball();
split_fire_ball();
}
printf("%d\n", result);
}