-
백준 - 20056 [C++]문제 풀이/백준 2023. 7. 18. 23:26반응형
이 문제는 시뮬레이션 문제이다. 시뮬레이션 문제 특성상 구현이 매우 복잡하지만 일단 구현하면 문제는 풀린다. 문제를 제대로 읽지 않아서 이동 시 범위를 넘어갔을 때 다시 순환형으로 돌아온다는 사실을 모르고 구현했다가 다시 풀었다. 모듈러 연산을 활용하여 연산 횟수를 줄이기 위해서는 인덱스가 1로 시작하면 매우 복잡하다. 따라서 입력을 받을 때 r과 c를 1씩 빼서 0부터 시작하도록 수정하였고, matrix의 한 요소를 벡터로 하여 항상 push 할 수 있도록 하여 구현을 그나마 간단하게 하였다.
어려운 구현 문제는 꼭 함수를 분리하여 추상화를 먼저 하고 순서를 짜놓은 뒤 세부 구현을 하는게 훨씬 간편하다.
#include <iostream> #include <vector> #include <queue> using namespace std; #define UP 0 #define UPRIGHT 1 #define RIGHT 2 #define DOWNRIGHT 3 #define DOWN 4 #define DOWNLEFT 5 #define LEFT 6 #define UPLEFT 7 typedef struct _fireball { int r; int c; int m; int s; int d; } fireball; vector<vector<vector<fireball>>> matrix; // 격자 int n; // 격자 크기 int f; // fireball count int k; // command count bool moveFunc(fireball& present) { int direction = present.d; int startR = present.r; int startC = present.c; int speed = present.s; int endR = startR; int endC = startC; switch (direction) { case UP: endR = (startR - speed) % n; if (endR < 0) { endR += n; } break; case UPRIGHT: endR = (startR - speed) % n; if (endR < 0) { endR += n; } endC = (startC + speed) % n; break; case RIGHT: endC = (startC + speed) % n; break; case DOWNRIGHT: endR = (startR + speed) % n; endC = (startC + speed) % n; break; case DOWN: endR = (startR + speed) % n; break; case DOWNLEFT: endR = (startR + speed) % n; endC = (startC - speed) % n; if (endC < 0) { endC += n; } break; case LEFT: endC = (startC - speed) % n; if (endC < 0) { endC += n; } break; case UPLEFT: endR = (startR - speed) % n; if (endR < 0) { endR += n; } endC = (startC - speed) % n; if (endC < 0) { endC += n; } break; } present.r = endR; present.c = endC; return true; } void move() { vector<vector<vector<fireball>>> tempMatrix(51, vector<vector<fireball>>(51, vector<fireball>())); for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (matrix[y][x].empty()) { continue; } for (fireball temp : matrix[y][x]) { bool result; result = moveFunc(temp); if (result) { tempMatrix[temp.r][temp.c].push_back(temp); } } } } matrix = tempMatrix; } void sumAndDivide() { vector<vector<vector<fireball>>> tempMatrix(51, vector<vector<fireball>>(51, vector<fireball>())); for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { if (matrix[y][x].size() == 1) { tempMatrix[y][x].push_back(matrix[y][x].front()); } if (matrix[y][x].size() >= 2) { fireball result; int size = matrix[y][x].size(); int mSum = 0; int sSum = 0; int direction = matrix[y][x].front().d; bool correct = true; int oddOrEven = -1; if (direction % 2 == 0) { oddOrEven = 0; } else { oddOrEven = 1; } for (auto& temp : matrix[y][x]) { mSum += temp.m; sSum += temp.s; if (oddOrEven == 0) // even { if (temp.d % 2 == 1) { correct = false; } } else // odd { if (temp.d % 2 == 0) { correct = false; } } } matrix[y][x].clear(); if (mSum / 5 != 0) { if (correct) { int ds[] = { 0, 2, 4, 6 }; for (int i = 0; i < 4; i++) { tempMatrix[y][x].push_back({ y, x, mSum / 5, sSum / size, ds[i] }); } } else { int ds[] = { 1,3,5,7 }; for (int i = 0; i < 4; i++) { tempMatrix[y][x].push_back({ y, x, mSum / 5, sSum / size, ds[i] }); } } } } } } matrix = tempMatrix; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int answer = 0; cin >> n >> f >> k; matrix = vector<vector<vector<fireball>>>(51, vector<vector<fireball>>(51, vector<fireball>())); for (int i = 0; i < f; i++) { int r, c, m, d, s; // 행, 열, 질량, 방향, 속력 cin >> r >> c >> m >> s >> d; matrix[r - 1][c - 1].push_back({ r - 1, c - 1, m, s, d }); } for (int i = 0; i < k; i++) { move(); sumAndDivide(); } for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { for (fireball& temp : matrix[y][x]) { answer += temp.m; } } } cout << answer << '\n'; return 0; }
반응형'문제 풀이 > 백준' 카테고리의 다른 글
백준 - 15591 [C++] (0) 2023.07.29 백준 - 17837 [C++] (0) 2023.07.20 백준 - 12851 [C++] (0) 2023.07.18 백준 - 9466 [C++] (2) 2023.07.18 백준 - 2146 [C++] (0) 2023.07.18