시뮬레이션 문제이다.
문제 흐름은 다음과 같다.
관건은 범위 제한이 없는 격자를 구현하는 것!
다음 위치가 격자 범위가 아니라면 scale함수를 통해 새로운 좌표를 설정해 주었다.
처음에 구성된 함수는 아래와 같은데, 주어진 4개 테케는 맞았는데 제출하니 0%에서 틀렸습니다. 가 나왔다.
if (nx > 0) {
return nx % N;
}
else if (nx == 0) {
return N;
}
else {
return N - (abs(nx) % N);
}
이유는 nx이 N과 동일할 때 nx & N 연산의 결과가 0이 나오는 경우의 수를 포함하지 못했기 때문이었다.
이 부분만 수정하니 통과가 되었는데, 질문검색을 통해 알아냈다.
파이어볼을 나타내는 구조체인 fireball을 정의하고 fireball type의 vector를 정의하여 문제를 풀었다.
입력 받는 파이어볼들을 순서대로 vector에 넣으며 그 index를 각 파이어볼의 번호로 사용하였는데, 이 번호는 나중에 겹치는 파이어볼이 있는지를 판단할 때 이용하였다.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
typedef struct fireball {
int num;
int x;
int y;
int m;
int s;
int d;
bool is_live;
} fireball;
int N, M, K, rst;
vector<fireball> FB;
vector<int> map[51][51];
int dx[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
int dy[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
void input() {
cin >> N >> M >> K;
for (int i = 0; i < M; i++) {
int r, c, m, s, d;
cin >> r >> c >> m >> s >> d;
fireball tmp = {i, r, c, m, s, d, true};
FB.push_back(tmp);
}
}
int is_range(int x) {
if (x >= 1 && x <= N) return true;
return false;
}
int scale(int nx) {
if (nx > N) nx = nx % N;
if (nx < 1) nx = N - abs(nx) % N;
return nx;
}
void move() {
for (int i = 0; i < FB.size(); i++) {
if (!FB[i].is_live) continue;
int nx = FB[i].x + FB[i].s * dx[FB[i].d];
int ny = FB[i].y + FB[i].s * dy[FB[i].d];
if (!is_range(nx)) nx = scale(nx);
if (!is_range(ny)) ny = scale(ny);
FB[i].x = nx;
FB[i].y = ny;
map[nx][ny].push_back(FB[i].num);
}
}
void adjust() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (map[i][j].size() < 2) continue;
int msum = 0, ssum = 0;
bool is_even = true, is_odd = true;
for (int idx = 0; idx < map[i][j].size(); idx++) {
int num = map[i][j][idx];
msum += FB[num].m;
ssum += FB[num].s;
if (FB[num].d % 2 == 0) is_odd = false;
else is_even = false;
FB[num].is_live = false;
}
int nm = msum / 5;
int ns = ssum / map[i][j].size();
if (nm == 0) continue;
if (is_even || is_odd) { // 0, 2, 4, 6
int nd = 0;
for (int iter = 0; iter < 4; iter++) {
fireball tmp = { FB.size(), i, j, nm, ns, nd, true };
FB.push_back(tmp);
nd += 2;
}
}
else { // 1, 3, 5, 7
int nd = 1;
for (int iter = 0; iter < 4; iter++) {
fireball tmp = { FB.size(), i, j, nm, ns, nd, true };
FB.push_back(tmp);
nd += 2;
}
}
}
}
}
void reset() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
while (!map[i][j].empty()) {
map[i][j].pop_back();
}
}
}
}
void cal_rst() {
rst = 0;
for (int idx = 0; idx < FB.size(); idx++) {
if (!FB[idx].is_live) continue;
rst += FB[idx].m;
}
}
void solve() {
while (K-- > 0) {
reset(); // make map vector empty
move();
adjust();
}
cal_rst();
}
int main() {
input();
solve();
cout << rst << endl;
}