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차배열을 회전하는 문제가 잘 출제되고 있으니, 꼭 기억할 것!
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;
}