[백준/BOJ] 백준 20057번 : 마법사 상어와 토네이도
2021. 2. 9. 00:30ㆍ알고리즘 문제풀이
here가 (0,0)에 도착했을 때 종료하는 조건으로 문제를 풀었다. 방향에 따라 모래가 흩날리는 위치를 지정해 놓았고, 방향에 따라 a지점의 위치를 설정했다. 그리고 직선으로 움직이는 길이가 언제 길어지는지 판단하여 설정했다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
int n;
int board[499][499];
int dxdy[4][2] = { {0,-1},{-1,0},{0,1},{1,0} };
int spread_dxdy[9][2] = { {-1,1},{-1,0},{-1,-1},{-2,0},{1,1},{1,0},{1,-1},{2,0},{0,-2} };
int spread_dxdy2[9][2] = { {-1,-1},{-1,0},{-1,1},{-2,0},{1,-1},{1,0},{1,1},{2,0},{0,2} };
int spread_dxdy3[9][2] = { {1,-1},{0,-1},{-1,-1},{0,-2},{1,1},{0,1},{-1,1},{0,2},{-2,0} };
int spread_dxdy4[9][2] = { {-1,-1},{0,-1},{1,-1},{0,-2},{-1,1},{0,1},{1,1},{0,2},{2,0} };
int Solve()
{
int result = 0;
pair<int, int> here = make_pair((n - 1) / 2, (n - 1) / 2);
int here_dir = 0;
int len = 1;
while (1)
{
if (here.first == 0 && here.second == 0)
return result;
for (int j = 0; j < len; j++)
{
//(0,0)에 도착했을때
if (here.first == 0 && here.second == 0)
return result;
pair<int, int> there = make_pair(here.first + (dxdy[here_dir][0]), here.second + (dxdy[here_dir][1]));
int there_sand = board[there.first][there.second];
board[there.first][there.second] = 0;
//모래가 날리는 흩날리는 9개 방향
for (int i = 0; i < 9; i++)
{
pair<int, int> spread_there;
if (here_dir == 0)
spread_there = make_pair(there.first + spread_dxdy[i][0], there.second + spread_dxdy[i][1]);
else if (here_dir == 2)
spread_there = make_pair(there.first + spread_dxdy2[i][0], there.second + spread_dxdy2[i][1]);
else if (here_dir == 1)
spread_there = make_pair(there.first + spread_dxdy3[i][0], there.second + spread_dxdy3[i][1]);
else if (here_dir == 3)
spread_there = make_pair(there.first + spread_dxdy4[i][0], there.second + spread_dxdy4[i][1]);
int spread_sand;
if (i == 0 || i == 4)
spread_sand = there_sand * 1 / 100;
else if (i == 1 || i == 5)
spread_sand = there_sand * 7 / 100;
else if (i == 2 || i == 6)
spread_sand = there_sand * 10 / 100;
else if (i == 3 || i == 7)
spread_sand = there_sand * 2 / 100;
else if (i == 8)
spread_sand = there_sand * 5 / 100;
//흩날리는 구역이 board안 일때
if (spread_there.first >= 0 && spread_there.first < n && spread_there.second >= 0 && spread_there.second < n)
board[spread_there.first][spread_there.second] += spread_sand;
//흩날리는 구역이 board밖 일때
else
result += spread_sand;
}
//a지점
pair<int, int> a_point;
if (here_dir == 0)
a_point = make_pair(there.first, there.second - 1);
else if (here_dir == 2)
a_point = make_pair(there.first, there.second + 1);
else if (here_dir == 1)
a_point = make_pair(there.first - 1, there.second);
else if (here_dir == 3)
a_point = make_pair(there.first + 1, there.second);
//a지점이 board안 일때
if (a_point.first >= 0 && a_point.first < n && a_point.second >= 0 && a_point.second < n)
board[a_point.first][a_point.second] += there_sand - ((there_sand * 1 / 100 * 2) + (there_sand * 7 / 100 * 2) + (there_sand * 10 / 100 * 2) + (there_sand * 2 / 100 * 2) + (there_sand * 5 / 100));
//a지점이 board밖 일때
else
result += there_sand - ((there_sand * 1 / 100 * 2) + (there_sand * 7 / 100 * 2) + (there_sand * 10 / 100 * 2) + (there_sand * 2 / 100 * 2) + (there_sand * 5 / 100));
here = there;
}
int there_dir;
if (here_dir == 0)
there_dir = 3;
else if (here_dir == 1)
{
there_dir = 0;
len++; //len이 길어지는 때
}
else if (here_dir == 2)
there_dir = 1;
else if (here_dir == 3)
{
there_dir = 2;
len++; //len이 길어지는 때
}
here_dir = there_dir;
}
return result;
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
int input;
cin >> input;
board[i][j] = input;
}
cout << Solve();
}
'알고리즘 문제풀이' 카테고리의 다른 글
[백준/BOJ] 백준 20055번 : 컨베이어 벨트 위의 로봇 (0) | 2021.02.09 |
---|---|
[백준/BOJ] 백준 20058번 : 마법사 상어와 파이어스톰 (0) | 2021.02.09 |
[백준/BOJ] 백준 17825번 : 주사위 윷놀이 (0) | 2021.02.09 |
[백준/BOJ] 백준 17822번 : 원판 돌리기 (0) | 2021.02.09 |
[백준/BOJ] 백준 17837번 : 새로운 게임 2 (0) | 2021.02.09 |