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

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

by paysmile 2021. 9. 30.

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 = 505;
int map[MAX][MAX];
int n;
struct MOVE { int x, y, v; };
MOVE mv_l[9] = { { -2,0,2 },{ -1,-1,10 },{ -1,0,7 },{ -1,1,1 },{ 0,-2,5 },{ 1,-1,10 },{ 1,0,7 },{ 1,1,1 },{ 2,0,2 } };
MOVE mv_r[9] = { { -2,0,2 },{ -1,-1,1 },{ -1,0,7 },{ -1,1,10 },{ 0,2,5 },{ 1,-1,1 },{ 1,0,7 },{ 1,1,10 },{ 2,0,2 } };
MOVE mv_up[9] = { { -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 } };
MOVE mv_down[9] = { { -1,-1,1 },{ -1,1,1 },{ 0,-2,2 },{ 0,-1,7 },{ 0,1,7 },{ 0,2,2 },{ 1,-1,10 },{ 1,1,10 },{ 2,0,5 } };
pair<int, int> loc;
int answer = 0;
int counts = 1;

void MoveLeft() {
	loc.second = loc.second - 1;
	int value = map[loc.first][loc.second];
	map[loc.first][loc.second] = 0;
	int tmp = value;

	for (int k = 0; k < 9; k++) {
		int movei = loc.first + mv_l[k].x;
		int movej = loc.second + mv_l[k].y;
		int v = mv_l[k].v;
		v = value * v / 100;

		if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
			map[movei][movej] += v;
		}
		else
			answer += v;
		tmp -= v;
	}

	int movei = loc.first;
	int movej = loc.second - 1;
	if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
		map[movei][movej] += tmp;
	}
	else
		answer += tmp;
}

void MoveDown() {
	loc.first = loc.first + 1;
	int value = map[loc.first][loc.second];
	map[loc.first][loc.second] = 0;
	int tmp = value;

	for (int k = 0; k < 9; k++) {
		int movei = loc.first + mv_down[k].x;
		int movej = loc.second + mv_down[k].y;
		int v = mv_down[k].v;
		v = value * v / 100;

		if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
			map[movei][movej] += v;
		}
		else
			answer += v;
		tmp -= v;
	}

	int movei = loc.first + 1;
	int movej = loc.second;
	if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
		map[movei][movej] += tmp;
	}
	else
		answer += tmp;
}

void MoveRight() {
	loc.second = loc.second + 1;
	int value = map[loc.first][loc.second];
	map[loc.first][loc.second] = 0;
	int tmp = value;

	for (int k = 0; k < 9; k++) {
		int movei = loc.first + mv_r[k].x;
		int movej = loc.second + mv_r[k].y;
		int v = mv_r[k].v;
		v = value * v / 100;

		if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
			map[movei][movej] += v;
		}
		else
			answer += v;
		tmp -= v;
	}

	int movei = loc.first;
	int movej = loc.second + 1;
	if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
		map[movei][movej] += tmp;
	}
	else
		answer += tmp;
}

void MoveUp() {
	loc.first = loc.first - 1;
	int value = map[loc.first][loc.second];
	map[loc.first][loc.second] = 0;
	int tmp = value;

	for (int k = 0; k < 9; k++) {
		int movei = loc.first + mv_up[k].x;
		int movej = loc.second + mv_up[k].y;
		int v = mv_up[k].v;
		v = value * v / 100;

		if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
			map[movei][movej] += v;
		}
		else
			answer += v;
		tmp -= v;
	}

	int movei = loc.first - 1;
	int movej = loc.second;
	if (movei >= 0 && movei < n && movej >= 0 && movej < n) {
		map[movei][movej] += tmp;
	}
	else
		answer += tmp;
}

int main(void) {
	cin >> n;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> map[i][j];
		}
	}
	//왼, 아래, 우, 위 (0,1,2,3)
	int dir = 0;

	loc = make_pair(n / 2, n / 2);
	while (counts < n) {
		for (int k = 0; k < 2; k++) {
			for (int j = 0; j < counts; j++) {
				if (dir == 0)	MoveLeft();
				else if (dir == 1)	MoveDown();
				else if (dir == 2)	MoveRight();
				else if (dir == 3)	MoveUp();
			}
			dir++;
			if (dir == 4)	dir = 0;
		}
		counts++;
	}

	for (int k = 0; k < n; k++) {
		MoveLeft();
	}
	cout << answer << endl;
}

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

컨베이어 벨트 위의 로봇  (0) 2021.10.12
마법사 상어와 파이어볼 C++  (0) 2021.09.30
상어 초등학교 C++  (0) 2021.09.18
마법사 상어와 블리자드 C++  (0) 2021.09.18
백준 모노미노도미노 2 C++  (0) 2021.07.26