[백준/BOJ] 백준 20057번 : 마법사 상어와 토네이도

2021. 2. 9. 00:30알고리즘 문제풀이

www.acmicpc.net/problem/20057

 

20057번: 마법사 상어와 토네이도

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

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();

}