코딩테스트/시뮬레이션
[시뮬레이션] 백준 20056 마법사 상어와 파이어볼 C++
유(YOO)
2022. 2. 8. 10:47
#include<bits/stdc++.h>
using namespace std;
struct Ball {
int m, s, d; // 질량, 속력, 방향
Ball* next; // 같은 위치의 볼들
};
struct State {
int sumM, sumS, sumD, dir, nCnt, lCnt; // 질량 합, 속력 합, 방향 합, 최종 방향, 현재 볼 개수, 나중 볼 개수
Ball balls; // 헤드 노드 (포인터 선언은 까다로움)
};
int bufCnt, N, M, K, ans;
int dx[8] = { 0,1,1,1,0,-1,-1,-1 };
int dy[8] = { -1,-1,0,1,1,1,0,-1 };
Ball ball[10000000];
State board[52][52];
void addBall(int r, int c, int m, int s, int d) {
ball[bufCnt].m = m;
ball[bufCnt].s = s;
ball[bufCnt].d = d;
ball[bufCnt].next = nullptr;
Ball* temp = (&ball[bufCnt]);
bufCnt++;
Ball* ptr = (&board[r][c].balls);
temp->next = ptr->next;
ptr->next = temp;
}
void start() {
for (int t = 0; t < K; t++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (board[i][j].nCnt == 0) continue;
Ball* ptr = (&board[i][j].balls);
while (ptr->next) {
int newX = j + (dx[(ptr->next->d)] * (ptr->next->s));
int newY = i + (dy[(ptr->next->d)] * (ptr->next->s));
newX = (newX % N) + 1; newY = (newY % N) + 1; // 배열 인덱스 나머지 연산
if (newX <= 0) newX = N + newX;
if (newY <= 0) newY = N + newY;
if (newX > N) newX = (newX - N);
if (newY > N) newY = (newY - N);
board[newY][newX].sumM += ptr->next->m;
board[newY][newX].sumS += ptr->next->s;
board[newY][newX].sumD += ptr->next->d; // 공 하나일 경우를 위하여 방향 값 저장해야 함
if ((ptr->next->d) & 1) board[newY][newX].dir += 1; // 방향 결정
board[newY][newX].lCnt += 1;
ptr->next = ptr->next->next;
}
board[i][j].nCnt = 0;
}
}
ans = 0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (board[i][j].lCnt > 1) { // 2개 이상
int m = floor(board[i][j].sumM / 5);
int s = floor(board[i][j].sumS / board[i][j].lCnt);
int dir = 1;
if ((board[i][j].lCnt == board[i][j].dir) || (board[i][j].dir == 0)) dir = 0;
if (m != 0) { // 질량 0이면 소멸
for (int k = 0; k < 4; k++) { // 인덱스 조심
addBall(i, j, m, s, dir);
board[i][j].nCnt++;
ans += m;
dir = dir + 2;
}
}
}
else if (board[i][j].lCnt == 1) { // 공 하나일 경우 조심
addBall(i, j, board[i][j].sumM, board[i][j].sumS, board[i][j].sumD);
board[i][j].nCnt = board[i][j].lCnt;
ans += board[i][j].sumM;
}
board[i][j].lCnt = 0;
board[i][j].sumM = 0;
board[i][j].sumS = 0;
board[i][j].sumD = 0;
board[i][j].dir = 0;
}
}
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> N >> M >> K;
for (int i = 0; i < M; i++) {
int r, c, m, s, d;
cin >> r >> c >> m >> s >> d;
addBall(r, c, m, s, d);
board[r][c].nCnt++;
}
start();
cout << ans;
}