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

마법사 상어와 파이어스톰 C++

by paysmile 2021. 9. 22.

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

 

20058번: 마법사 상어와 파이어스톰

마법사 상어는 파이어볼과 토네이도를 조합해 파이어스톰을 시전할 수 있다. 오늘은 파이어스톰을 크기가 2N × 2N인 격자로 나누어진 얼음판에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c

www.acmicpc.net

#include <iostream>
#include <math.h>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAX = 70;
int n, q,l;
int map[MAX][MAX];
int tmp[MAX][MAX];
int sz;
struct MOVE{ int x,y; };
MOVE mv[4] = { {1,0}, {-1,0}, {0,1}, {0,-1} };
int maxsize = 0;
int counts = 0;

void copymap() {
	for (int i = 0; i < sz; i++) {
		for (int j = 0; j < sz; j++) {
			tmp[i][j] = map[i][j];
		}
	}
}

void Rotate(int mi,int mj) {
	int li = pow(2, l);

	int si = mi + li - 1;
	int sj = mj;
	for (int i = mi; i < mi + li; i++) {
		si = mi + li - 1;
		for (int j = mj; j < mj + li; j++) {
			map[i][j] = tmp[si][sj];
			si--;
		}
		sj++;
	}
}

void Divide() {
	copymap();

	for (int i = 0; i < sz; i+=pow(2,l)) {
		for (int j = 0; j < sz; j+=pow(2,l)) {
			Rotate(i, j);
		}
	}
}

void MeltingIce() {
	copymap();

	for (int i = 0; i <sz; i++) {
		for (int j = 0; j < sz; j++) {
			int count = 0;

			for (int k = 0; k < 4; k++) {
				int movei = i + mv[k].x;
				int movej = j + mv[k].y;

				if (movei >= 0 && movei < sz && movej >= 0 && movej < sz) {
					if (tmp[movei][movej] > 0) {
						count++;
					}
				}
			}
			if (count < 3 && map[i][j] >0) {
				map[i][j] -= 1;
			}
		}
	}
}

void dfs(int mi, int mj) {
	for (int k = 0; k < 4; k++) {
		int movei = mi + mv[k].x;
		int movej = mj + mv[k].y;

		if (movei >= 0 && movei < sz && movej >= 0 && movej < sz) {
			if (tmp[movei][movej] == 0 && map[movei][movej] > 0) {
				tmp[movei][movej] = 1;
				counts += 1;
				dfs(movei, movej);
			}
		}
	}
}

int main(void) {
	cin >> n >> q;

	sz = pow(2, n);
	for (int i = 0; i < sz; i++) {
		for (int j = 0; j < sz; j++) {
			cin >> map[i][j];
		}
	}

	for (int testcase = 0; testcase < q; testcase++) {
		cin >> l;

		Divide();
		MeltingIce();
	}

	int answer = 0;

	for (int i = 0; i < sz; i++) {
		for (int j = 0; j < sz; j++) {
			answer += map[i][j];
		}
	}
	
	memset(tmp, 0, sizeof(tmp));
	for (int i = 0; i < sz; i++) {
		for (int j = 0; j < sz; j++) {
			if (map[i][j] > 0 && tmp[i][j] == 0) {
				tmp[i][j] = 1;
				counts = 1;
				dfs(i, j);
				maxsize = max(counts, maxsize);
			}
		}
	}
	cout << answer << endl;
	cout << maxsize << endl;
}

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

주사위 굴리기 2  (0) 2021.12.04
원판 돌리기 C++  (0) 2021.10.16
상어 중학교 C++  (0) 2021.09.18
원판 돌리기  (0) 2021.04.20
마법사 상어와 파이어스톰  (0) 2021.04.01