티스토리 뷰
https://www.acmicpc.net/problem/20056
20056번: 마법사 상어와 파이어볼
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치
www.acmicpc.net
난이도
구현 / 난이도 ⭐️⭐️⭐️ / 2시간
크게 구현이 어렵지 않지만, 함수로 나누지 않고 main함수에 모든 코드를 넣다보니깐 오류를 잡기 어려웠다.
사소한 실수가 너무 많았어서 한 4~5부분은 고친 후에야 문제에서 주어진 테스트케이스를 충족시킬 수 있었다.
// https://www.acmicpc.net/problem/20056
// 마법사 상어와 파이어볼
#include <stdio.h>
#include <vector>
#include <cmath>
#include <set>
#include <utility>
#include <iostream>
using namespace std;
int dirx[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int diry[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int n, m, k;
// check point 5) 나누기 4를 하고있었는데, 틀린 구현이었다. 0 ~ n-1 구간안으로 x가 들어오도록 더하고 빼주는게 헷갈리지 않는다.
int adjust(int x)
{
if (x < 0)
{
while (x < 0)
{
x += n;
}
}
else if (x > 0)
{
while (x > n - 1)
{
x -= n;
}
}
return x;
}
int main()
{
scanf("%d %d %d", &n, &m, &k);
vector<int> arr[51][51]; // 51
vector<vector<int> > ball(m, vector<int>(5, 0));
for (int i = 0; i < m; i++)
{
// ri, ci, mi, si, di
scanf("%d %d %d %d %d", &ball[i][0], &ball[i][1], &ball[i][2], &ball[i][3], &ball[i][4]);
// check point 4) 설계는 0 0 부터로 했는데 문제에서 주어지는 좌표는 1 1부터이다.
ball[i][0] -= 1;
ball[i][1] -= 1;
}
int dir, speed, massive;
int x, y, newx, newy;
for (int i = 0; i < k; i++)
{
set<pair<int, int> > sett;
// check point 3) 마법을 k번 반복하며 ball 벡터길이가 달라질 수 있는데, j < n조건을 사용하고 있었다. 세그먼테이션폴트.
for (int j = 0; j < ball.size(); j++)
{
x = ball[j][0];
y = ball[j][1];
speed = ball[j][3];
dir = ball[j][4];
newx = x + (dirx[dir] * speed);
newy = y + (diry[dir] * speed);
newx = adjust(newx);
newy = adjust(newy);
arr[newx][newy].push_back(j);
sett.insert(make_pair(newx, newy));
}
set<pair<int, int> >::iterator iter;
vector<vector<int> > newball;
int ball_index;
bool all_same_dir;
int cur_dir;
for (iter = sett.begin(); iter != sett.end(); iter++)
{
x = iter->first;
y = iter->second;
speed = 0;
massive = 0;
cur_dir = -1;
all_same_dir = true;
if (arr[x][y].size() == 0)
continue;
if (arr[x][y].size() == 1)
{
ball_index = arr[x][y][0];
vector<int> temp;
temp.push_back(x);
temp.push_back(y);
temp.push_back(ball[ball_index][2]);
temp.push_back(ball[ball_index][3]);
temp.push_back(ball[ball_index][4]);
newball.push_back(temp);
arr[x][y].clear();
continue;
}
for (int j = 0; j < arr[x][y].size(); j++)
{
ball_index = arr[x][y][j];
massive += ball[ball_index][2];
speed += ball[ball_index][3];
// check point 2) 나머지가 같은지 다른지 비교해야하는데 숫자 자체를 비교하고 있어서 항상 false가 나오고 있었다.
if (cur_dir == -1)
{
if (ball[ball_index][4] % 2 == 0)
{
cur_dir = 0;
}
else
{
cur_dir = 1;
}
}
else
{
if (cur_dir != (ball[ball_index][4] % 2))
all_same_dir = false;
}
// check point 2) end
}
massive = massive / 5;
speed = speed / arr[x][y].size();
if (massive != 0)
{
for (int p = 0; p < 8; p += 2)
{
vector<int> temp;
temp.push_back(x);
temp.push_back(y);
temp.push_back(massive);
temp.push_back(speed);
if (!all_same_dir)
{
temp.push_back(p + 1);
}
else
{
temp.push_back(p);
}
newball.push_back(temp);
}
}
arr[x][y].clear();
}
// check point 1) 2차원 벡터 copy
for (int p = 0; p < ball.size(); p++)
{
ball[p].clear();
}
ball.clear();
ball.assign(newball.size(), vector<int>(5));
copy(newball.begin(), newball.end(), ball.begin());
}
int result = 0;
for (int i = 0; i < ball.size(); i++)
{
result += ball[i][2];
}
printf("%d", result);
}
문법을 몰라서 많은 시간을 소요했다.
2차원 벡터 비우기.
2차원 벡터 복사하기.
'알고리즘 > [문제풀이] BOJ' 카테고리의 다른 글
[BOJ] 29237 - 어른 상어 (0) | 2021.10.20 |
---|---|
[BOJ] 20055 - 컨베이어 벨트 위의 로봇 (0) | 2021.10.18 |
[BOJ] 20057 - 마법사 상어와 토네이도 (0) | 2021.10.15 |
[BOJ] 5568 - 카드 놓기 (0) | 2021.10.04 |
[BOJ] 1593 - 문자 해독 (0) | 2021.10.02 |