Study/Coding Test
[백준] 마법사 상어와 비바라기
_gayeon
2021. 10. 14. 21:40
https://www.acmicpc.net/problem/21610
21610번: 마법사 상어와 비바라기
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기
www.acmicpc.net
구현에 어렵지 않은 문제였다.
memset 사용을 위해서는 include <cstring> 잊지 말자.
vector의 erase 함수는 size를 0으로 만드는 기능을 한다.
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int N, M;
int map[51][51];
bool visited[51][51];
vector<vector<int>> movement;
vector< pair<int, int> > cloud;
int dr[9] = { 0,0,-1,-1,-1,0,1,1,1 };
int dc[9] = { 0,-1,-1,0,1,1,1,0,-1 };
void init() {
for (int i = 0; i < 51; i++) {
memset(visited[i], false, sizeof(51));
memset(map[i], 0, sizeof(51));
}
movement.clear();
cloud.clear();
}
void input() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//freopen("input.txt", "r", stdin);
cin >> N >> M;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
cin >> map[i][j];
}
}
for (int i = 0; i < M; i++) {
int d, s;
cin >> d >> s;
movement.push_back({ d,s });
}
}
bool inRange(int r, int c) {
return r >= 1 && r <= N && c >= 1 && c <= N;
}
void print() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
cout << map[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void solve(int d, int s) {
vector< pair<int,int> > new_cloud;
//1,2번
for (int i = 0; i < cloud.size(); i++) {
int row = cloud[i].first;
int col = cloud[i].second;
int nr = row + dr[d] * (s%N);
int nc = col + dc[d] * (s%N);
if (nr < 1) nr = N + nr;
else if (nr > N) nr = nr - N;
if (nc < 1) nc = N + nc;
else if (nc > N) nc = nc - N;
visited[nr][nc] = true;
map[nr][nc]++;
new_cloud.push_back({ nr, nc });
}
cloud.clear();
//4번
for (int i = 0; i < new_cloud.size(); i++) {
int row = new_cloud[i].first;
int col = new_cloud[i].second;
int cnt = 0; //물이 있는 바구니 수
for (int k = 2; k <= 8; k += 2) {
int nr = row + dr[k];
int nc = col + dc[k];
if (inRange(nr, nc)) { //경계에 있는 경우
if (map[nr][nc] > 0) {
cnt++;
}
}
}
map[row][col] += cnt;
}
//3번
new_cloud.clear();
//5번
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (!visited[i][j] && map[i][j] >= 2) {
cloud.push_back({ i,j });
map[i][j] -= 2;
}
}
}
//visited 초기화
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
visited[i][j] = false;
}
}
}
int main() {
init();
input();
//초기 구름
cloud.push_back({ N,1 });
cloud.push_back({ N,2 });
cloud.push_back({ N - 1,1 });
cloud.push_back({ N - 1,2 });
for (int i = 0; i < M; i++) {
solve(movement[i][0], movement[i][1]);
}
int answer = 0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
answer += map[i][j];
}
}
cout << answer << endl;
return 0;
}