728x90
🔗 문제 링크
https://www.acmicpc.net/problem/20056
💡 문제 풀이 및 해석
시뮬레이션 문제인 만큼 문제의 최적화보다는 설명한 그대로 구현해야 한다. 주의할 점만 적어놓겠습니다.
- 파이어볼이 조건에 맞게 이동한다.
1-1. 조건대로 이동할 때, 파이어볼이 맵 밖으로 나가는 경우는 반대쪽에서 나오게 설정해야 한다.
1-2. 파이어볼이 이동하기 전에 기존에 맵에 저장되어 있던 파이어볼의 정보는 초기화 시켜줘야 한다. - 이동한 파이어볼은 분열한다.
2-1. 분열하면서 주의할 점은 모두 짝수 or 홀수 방향인 것을 정해줘야 한다는 점이다. (따로, 체크를 해야함)
2-2. 한 번만 이동해도 분열은 시켜준 뒤에 질량을 측정해야 한다.
이 과정을 K번 반복한다.
⭐️ 정답 코드 및 설명
#include <iostream>
#include <vector>
#define X 0246
using namespace std;
int N, M, K;
int next_y[] = {0, 1, 1, 1, 0, -1, -1, -1};
int next_x[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dir_even[] = {0, 2, 4, 6};
int dir_odd[] = {1, 3, 5, 7};
struct FIREBALL {
int x;
int y;
int weight;
int fast;
int dir;
};
vector<FIREBALL> FireBalls;
vector<FIREBALL> Map[51][51];
void Init() {
cin >> N >> M >> K;
for (int i = 0; i < M; i++) {
int r, c, m, s, d;
cin >> r >> c >> m >> s >> d;
FireBalls.push_back({r, c, m, s, d});
}
}
void ClearMap() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
Map[i][j].clear();
}
}
}
void Move() {
ClearMap();
for (int i = 0; i < FireBalls.size(); i++) {
auto fireball = FireBalls[i];
int nx = fireball.x + next_x[fireball.dir] * (fireball.fast % N);
int ny = fireball.y + next_y[fireball.dir] * (fireball.fast % N);
if (nx > N) nx -= N;
if (nx < 1) nx += N;
if (ny > N) ny -= N;
if (ny < 1) ny += N;
fireball.x = nx;
fireball.y = ny;
Map[nx][ny].push_back(fireball);
}
}
void Div() {
vector<FIREBALL> tempFireBall;
for (int x = 1; x <= N; x++) {
for (int y = 1; y <= N; y++) {
if (Map[x][y].size() == 0) continue;
if (Map[x][y].size() == 1) {
tempFireBall.push_back(Map[x][y][0]);
continue;
}
int weightSum = 0, fastSum = 0, cnt = Map[x][y].size();
int dir = -1;
for (int i = 0; i < Map[x][y].size(); i++) {
weightSum += Map[x][y][i].weight;
fastSum += Map[x][y][i].fast;
if (dir == -1) dir = Map[x][y][i].dir % 2;
else if (dir != Map[x][y][i].dir % 2) dir = X;
}
int weight = weightSum / 5;
int fast = fastSum / cnt;
if (weight == 0) continue;
if (dir == X) {
for (int i = 0; i < 4; i++) {
tempFireBall.push_back({x, y, weight, fast, dir_odd[i]});
}
} else {
for (int i = 0; i < 4; i++) {
tempFireBall.push_back({x, y, weight, fast, dir_even[i]});
}
}
}
}
FireBalls = tempFireBall;
}
int Sol() {
int answer = 0;
Init();
while (K > 0) {
K--;
Move();
Div();
}
for (auto i: FireBalls) answer += i.weight;
return answer;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cout << Sol();
return 0;
}
🤔 문제 후기
문제를 이해하는 것에는 크게 문제가 없지만, 문제를 풀 때, 원래 습관이 Map[열][행]
이런식으로 하다보니 next_x, next_y
의 설정을 반대로해서 생각보다 풀기가 너무 힘들었다. 그래도 x,y 방향만 바꾸니 바로 풀리는 것을 보니 생각보다 그렇게 어려운 문제는 아니였다.
728x90
'문제풀이 > 알고리즘 문제 풀이' 카테고리의 다른 글
[ 백준 20057 ] 마법사 상어와 토네이도 (C++) - 시뮬레이션 (0) | 2024.10.19 |
---|---|
[ 백준 21610 ] 마법사 상어와 비바라기 (C++) - 시뮬레이션 (3) | 2024.10.13 |
[ 프로그래머스 PCCP 기출문제 2번 ] 퍼즐 게임 챌린지 (C++) - 이분 탐색 (0) | 2024.09.24 |
[ 백준 1277 ] 발전소 설치 (C++) - 그래프 이론, 구현 (0) | 2024.09.23 |
[ 백준 17142 ] 연구소 3 (C++) - BFS, 시뮬레이션 (0) | 2024.09.12 |