Study/Coding Test

[백준] 마법사 상어와 토네이도

_gayeon 2021. 10. 15. 22:13

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

 

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

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

www.acmicpc.net

 

 

요즘 삼성 출제 경향이 단순구현인 것 같다. (계속 구현 문제만 푸는중)

 

2차배열을 회전하는 문제가 잘 출제되고 있으니, 꼭 기억할 것!

https://velog.io/@domybest/2%EC%B0%A8%EC%9B%90-%EB%B0%B0%EC%97%B4-%ED%9A%8C%EC%A0%84%EC%8B%9C%ED%82%A4%EA%B8%B0

 

2차배열 copy도 기억하기!

 

https://dbstndi6316.tistory.com/282

#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

int answer;
int N;
int total_sand;
int board[500][500];

int dr[4] = { 0,1,0,-1 };
int dc[4] = { -1,0,1,0 };
double ratio[5][5] = {
	{0,0,0.02,0,0},
	{0,0.1,0.07,0.01,0},
	{0.05,-1,0,0,0},
	{0,0.1,0.07,0.01,0},
	{0,0,0.02,0,0} };

void init() {
	for (int i = 0; i < 500; i++) {
		memset(board[i], 0, sizeof(board[i]));
	}
}

void rotate() {
	double temp[5][5];
	memcpy(temp, ratio, sizeof(ratio));

	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 5; j++) {
			ratio[5 - j - 1][i] = temp[i][j];
		}
	}
}

void input() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cin >> board[i][j];
			total_sand += board[i][j];
		}
	}
}

void print() {
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cout << board[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}

bool inRange(int r, int c) {
	return r >= 0 && r < N&& c >= 0 && c < N;
}

void wind(int row, int col) {
	int sand = board[row][col];
	int rest = sand;
	int rest_row = 0;
	int rest_col = 0;

	for (int i = row - 2, r = 0; i <= row + 2; i++, r++) {
		for (int j = col - 2, c = 0; j <= col + 2; j++, c++) {
			if (ratio[r][c] > 0) {
				int moved = sand * ratio[r][c];
				rest -= moved;
				if (inRange(i,j)) {
					board[i][j] += moved;
				}
			}

			else if (ratio[r][c] == -1) {
				rest_row = i;
				rest_col = j;
			}

		}
	}
	if (inRange(rest_row, rest_col)) {
		board[rest_row][rest_col] += rest;
	}
	board[row][col] = 0;
}

void solve() {
	int tornado_row = (N - 1) / 2;
	int tornado_col = (N - 1) / 2;

	int increase = 1;
	int idx = 2;

	while (idx <= N * N) {
		if (increase % 2 != 0) {
			//왼쪽
			for (int i = 0; i < increase && idx <= N * N; i++) {
				tornado_col = tornado_col + dc[0];
				wind(tornado_row, tornado_col);
				idx++;
			}
			rotate();

			//아래
			for (int i = 0; i < increase && idx <= N * N; i++) {
				tornado_row = tornado_row + dr[1];
				wind(tornado_row, tornado_col);
				idx++;
			}
			rotate();
			increase++;
		}
		else {
			//오른쪽
			for (int i = 0; i < increase && idx <= N * N; i++) {
				tornado_col = tornado_col + dc[2];
				wind(tornado_row, tornado_col);
				idx++;
			}
			rotate();

			//위
			for (int i = 0; i < increase && idx <= N * N; i++) {
				tornado_row = tornado_row + dr[3];
				wind(tornado_row, tornado_col);
				idx++;
			}
			rotate();

			increase++;
		}
	}

	int total_rest = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			total_rest += board[i][j];
		}
	}

	answer = total_sand - total_rest;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	//freopen("input.txt", "r", stdin);

	init();
	input();
	solve();

	cout << answer << endl;
	return 0;
}