본문 바로가기
백준 알고리즘/구현

마법사 상어와 토네이도 C++

by paysmile 2021. 4. 6.

https://www.acmicpc.net/problem/20057

 

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

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

www.acmicpc.net

 

#include <iostream>

using namespace std;

const int MAX = 501;
int n;
int answer = 0;
int soil[MAX][MAX];
struct MOVE { int x, y; };
MOVE mv[4] = { {0,-1}, {1,0}, {0,1}, {-1,0} }; //왼쪽, 아래쪽, 오른쪽, 위쪽
int wind_x[4][10] = { {0,1,-1,2,1,-1,-2,1,-1,0}, {2,1,1,0,0,0,0,-1,-1,1}, {0,-1,1,-2,-1,1,2,-1,1,0}, {-2,-1,-1,0,0,0,0,1,1,-1} };
int wind_y[4][10] = { {-2,-1,-1,0,0,0,0,1,1,-1}, {0,-1,1,-2,-1,1,2,-1,1,0}, {2,1,1,0,0,0,0,-1,-1,1}, {0,-1,1,-2,-1,1,2,-1,1,0} };
int amount[9] = { 5,10,10,2,7,7,2,1,1 };

//wind[0] = { {0,-2,5}, {1,-1,10}, {-1,-1,10}, {2,0,2}, {1,0,7}, {-1,0,7}, {-2,0,2}, {1,1,1}, {-1,1,1} };
//wind[1] = { {2,0,5}, {1,-1,10}, {1,1,10}, {0,-2,2}, {0,-1,7}, {0,1,7}, {0,2,2}, {-1,-1,1 }, {-1,1,1} };
//wind[2] = { {0,2,5}, {-1,1,10}, {1,1,10}, {-2,0,2}, {-1,0,7}, {1,0,7}, {2,0,2}, {-1,-1,1}, {1,-1,1} };
//wind[3] = { {-2,0,5} , {-1,-1,10}, {-1,1,10}, {0,-2,2}, {0,-1,7}, {0,1,7}, {0,2,2}, {1,-1,1}, {1,1,1} };

void MoveWind(int x, int y, int dir) {
	int sum = soil[x][y];
	int mv = 0;

	for (int i = 0; i < 9; i++) {
		int m_wind = sum * 0.01 * amount[i];
		mv += m_wind;

		int movei = x + wind_x[dir][i];
		int movej = y + wind_y[dir][i];

		if (movei > 0 && movei <= n && movej > 0 && movej <= n) {
			soil[movei][movej] += m_wind;
		}
		else {
			answer += m_wind;
		}
	}
	soil[x][y] = 0;
	int movei = x + wind_x[dir][9];
	int movej = y + wind_y[dir][9];

	if (movei > 0 && movei <= n && movej > 0 && movej <= n) {
		soil[movei][movej] = soil[movei][movej] + (sum - mv);
	}
	else {
		answer = answer + (sum - mv);
	}
}

pair<int,int> Moveloc(int x, int y, int dir){
	pair<int, int> temp;

	if (dir == 0)
		temp = make_pair(x + mv[0].x, y + mv[0].y);
	else if (dir == 1)
		temp = make_pair(x + mv[1].x, y + mv[1].y);
	else if (dir == 2)
		temp = make_pair(x + mv[2].x, y + mv[2].y);
	else if (dir == 3)
		temp = make_pair(x + mv[3].x, y + mv[3].y);

	return temp;
}

int main(void) {
	cin >> n;

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> soil[i][j];
		}
	}

	int count = 1;
	int dir = 0;
	int x = n / 2 + 1;
	int y = n / 2 + 1;
	while (count <= n) {
		for (int i = 0; i < 2; i++) {
			for (int j = count; j > 0; j--) {
				pair<int, int> temp = Moveloc(x, y, dir);
				x = temp.first;
				y = temp.second;

				MoveWind(x, y, dir);
			}
			if (dir == 3)
				dir = 0;
			else
				dir += 1;
		}
		if (count == n)
			MoveWind(x, y, dir);
		count += 1;
	}

	cout << answer << endl;
}

'백준 알고리즘 > 구현' 카테고리의 다른 글

마법사 상어와 파이어볼 C++  (0) 2021.04.13
낚시왕 C++  (0) 2021.04.11
새로운 게임 2 C++  (0) 2021.03.19
주사위 윷놀이 C++  (0) 2021.03.10
모노미노도미노 2  (0) 2021.03.08