풀이 소요시간 : 약 50분
한 세달만에 프로그래머스
에서 백준
으로 넘어와 문제를 풀어보았다. 그 이유는 삼성기출 문제를 풀어보기 위함인데, 3달동안 실력이 꽤나 올라감을 체감했다. 동일한 유형이면서 골드5
난이도인 마법사 상어와 비바라기 문제보다 한단계 어려운 이 문제를 꽤나 수월하게 풀어냈기 때문이다.
30분만에 구현을 끝냈지만, 20분동안 구조체 문법 오류때문에 삽질을 하며 시간을 소요했다. 단순 구현 + 시뮬레이션 문제이기에 별다른 접근 방법은 없다.
#include<iostream>
#include<vector>
#include<map>
using namespace std;
#define MAX 987654321
int N, M, K;
int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; //세로 축
int dy[8] = { 0, 1, 1, 1, 0, -1, -1, -1 }; //가로 축
struct FireBall {
int x;
int y;
int m; //질량
int s; //방향
int d; //속도
};
vector<FireBall> Vector;
map<pair<int, int>, vector<FireBall>> Map;
void Input() {
cin >> N >> M >> K;
for (int i = 1; i <= M; i++)
{
int x, y, m, s, d;
cin >> x >> y >> m >> s >> d;
Vector.push_back({ x, y, m, s, d });
}
}
//좌표 변환기
pair<int, int> Make_Range(int x, int y) {
if (x == 0) x = N;
else if (x == N + 1) x = 1;
if (y == 0) y = N;
else if (y == N + 1) y = 1;
return { x, y };
}
int main()
{
Input();
//이동을 K 회 명령한다.
while (K--)
{
//Map 초기화
Map.clear();
//1. 모든 파이어볼의 이동
for (auto &E : Vector)
{
//고유 방향으로 속력만큼 이동 완료
for (int i = 0; i < E.s; i++)
{
pair<int, int> next = Make_Range(E.x + dx[E.d], E.y + dy[E.d]);
E.x = next.first;
E.y = next.second;
}
//이동된 파이어볼 정보 삽입
Map[{E.x, E.y}].push_back(E);
}
Vector.clear();
//기존 파이어볼 좌표는 초기화
//2. 같은 칸의 파이어볼 갯수가 2 이상이면 합치고 나눈다.
for (auto &E : Map)
{
if (E.second.size() == 1)
{
Vector.push_back(E.second.front());
continue;
}
else
{
vector<FireBall> V = E.second;
int Size = V.size();
int Weight = 0;
int Speed = 0;
int Odd = 0;
int Even = 0;
//무조건 4개로 나뉘게된다.
for (int i = 0; i < V.size(); i++)
{
Weight += V[i].m;
Speed += V[i].s;
if (V[i].d % 2 == 0) Even++;
else if (V[i].d % 2 == 1) Odd++;
}
//새로운 무게, 속력, 방향
Weight /= 5;
Speed /= Size;
if (Weight == 0) continue; //질량이 0인 경우 생성(X) 소멸된다.
if (Odd == Size || Even == Size)
{
for (int i = 0; i <= 6; i += 2)
{
Vector.push_back({ E.first.first, E.first.second, Weight, Speed, i });
}
}
else
{
for (int i = 0; i <= 6; i += 2)
{
Vector.push_back({ E.first.first, E.first.second, Weight, Speed, i + 1 });
}
}
//새로운 파이어볼 좌표 삽입 완료
}
}
}
//남아있는 파이어볼의 질량의 합
int Ans = 0;
for (auto &E : Vector)
{
Ans += E.m;
}
cout << Ans << '\n';
}