1. 풀이방법
- 구현 문제이고 문제풀이에 필요한 알고리즘은 딱히 없습니다.
- 조건을 파악한뒤 이제 파이어볼이 이동할수 있는 지도가 연결되어 있다는 것이 중요한 것 같습니다.
- N을 넘어가면 다시 1로 오는 것이죠.
- 방향은 친절하게도 지도모양으로 줘서 8방향탐색 dx,dy를 설정해주시면 되고,
- 저같은 경우 파이어볼들을 저장하는 벡터 하나와 각 단계에서 ground[51][51]을 벡터로 선언해서,
- x,y에 이동한 파이어 볼이 있을경우 push_back으로 각 좌표에 매달아주는 느낌으로 구현하였습니다.
- 그렇게 파이어볼이 모두 이동시킨뒤 ground(맵)을 보면서 파이어볼이 없는 좌표는 continue
- 한개있는 좌표는 그대로 다시 totalfireball에 push, 두개 이상인 것은 문제 조건에 맞춰 재조정한후
- 4개의 파이어볼을 다시 totalfireball에 push 해주었습니다.
- 각 단계에서 vector들 clear()를 해주었구요.
2. 주의사항
- 이게 s(속력)이 최대 1000이 될수도 있습니다.
- 그래서 단순히 0보다 작아지면 N을 더해주거나 N보다 커지면 0으로 만들거나 하려면 이 자체도 반복문 처리를 해주어
- 합니다 그래서 그냥 아래와 같이 처리하였습니다.
- int newx = ((totalfireball[i].x) + dx[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
int newy = ((totalfireball[i].y) + dy[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
- 250*N을 더해준 이유는 % 모듈러 연산을 할 때 음수가 나오는 것을 방지하기 위함인데
- N의 최솟값은 4이고 s의 최대값은 1000이므로 250*N은 1000보다 같거나 크면서 N 모듈러 연산에는 영향을 끼치지
- 않는 수로 설정하였습니다(N의배수 이므로)
3. 나의코드
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int N, M, K;
int dx[8] = { -1,-1,0,1,1,1,0,-1 };//8방향탐색
int dy[8] = { 0,1,1,1,0,-1,-1,-1 };
struct fireball {
int x,y,m, s, d;
};
vector<fireball> ground[51][51];
vector<fireball> totalfireball;
void inputs() {
cin >> N >> M >> K;
int tx, ty, tm, ts, td;
for(int i=0;i<M;i++){
cin >> tx >> ty>>tm>>ts>>td;
totalfireball.push_back({ tx-1,ty-1,tm,ts,td }); // 난 0~N-1
}
}
void groundclear() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
ground[i][j].clear();
}
}
}
void moveball() {
for (int i = 0; i < totalfireball.size(); i++) {
int newx = ((totalfireball[i].x) + dx[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
int newy = ((totalfireball[i].y) + dy[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
ground[newx][newy].push_back({ newx,newy,totalfireball[i].m,totalfireball[i].s,totalfireball[i].d });
}
}
void makenewball() {
for(int i=0;i<N;i++){
for (int j = 0; j < N; j++) {
if (ground[i][j].empty()) continue; //비어있으면.
else if (ground[i][j].size() == 1) { //파이어볼이 한개
totalfireball.push_back(ground[i][j][0]);
}
else { //두개 이상인 경우
int newm = 0; int news = 0;
for (int k = 0; k < ground[i][j].size(); k++) {
newm += ground[i][j][k].m;
news += ground[i][j][k].s;
}
newm = newm / 5;
if (newm == 0) continue;
news = news / ground[i][j].size();
bool check = false;
for (int k = 0; k < ground[i][j].size(); k++) { //모두 홀수?
if (ground[i][j][k].d % 2 == 0) { check = true; break; }
}
if (check == false) {
totalfireball.push_back({ i,j,newm,news,0 });
totalfireball.push_back({ i,j,newm,news,2 });
totalfireball.push_back({ i,j,newm,news,4 });
totalfireball.push_back({ i,j,newm,news,6 });
continue;
}
check = false;
for (int k = 0; k < ground[i][j].size(); k++) { //모두 짝수?
if (ground[i][j][k].d % 2 == 1) { check = true; break; }
}
if (check == false) {
totalfireball.push_back({ i,j,newm,news,0 });
totalfireball.push_back({ i,j,newm,news,2 });
totalfireball.push_back({ i,j,newm,news,4 });
totalfireball.push_back({ i,j,newm,news,6 });
continue;
}
// 둘다 아닐경우
totalfireball.push_back({ i,j,newm,news,1 });
totalfireball.push_back({ i,j,newm,news,3 });
totalfireball.push_back({ i,j,newm,news,5 });
totalfireball.push_back({ i,j,newm,news,7 });
}
}
}
}
long long getm() {
long long resultm = 0;
for (int i = 0; i < totalfireball.size(); i++) {
resultm += totalfireball[i].m;
}
return resultm;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
inputs();
while (K--) {
groundclear();
moveball();
totalfireball.clear();
makenewball();
}
cout << getm() << "\n";
return 0;
}
'알고리즘 문제풀이 > 구현' 카테고리의 다른 글
백준 10993 [C++] (0) | 2021.01.16 |
---|---|
백준 20061 [C++] (0) | 2020.12.28 |
백준 20055 [C++] (0) | 2020.12.23 |
백준 13458 [C++] (0) | 2020.12.15 |
백준 15685 [C++] (0) | 2020.12.08 |