알고리즘/삼성SW역량테스트기출

[백준 14502번 - 연구소] C++ 풀이

Ompang 2021. 9. 18. 02:50
728x90
반응형

백준 14502번.

벽 3개를 추가로 세워서 바이러스가 퍼지지 않는 안전영역의 최대값을 구하는 문제이다.

 

사용한 알고리즘

- 브루트포스

- bfs

 

처음에는 벽 3개를 치는 경우의 수중 쳐낼 수 있는 가지수가 없나 생각을 해봤는데, 내 머리로는 도저히 떠오르지 않아서 그냥 다 구해보기로 했다. 3 <= N, M <= 8 이므로, map 최대 크기는 2의 6승. 그리고 벽 3개를 칠 가지수는 약 2의 18승 = 약 262,144개 이고, 각 경우의 수에 bfs 를 돌릴 경우 약 2의 12승, 더하면 약 2의 30승...... 대략 10억... 안되겠는데? 싶었지만 일단 코드를 짜서 제출했는데 맞았다... 뭐지..? 1과, 2가 이렇게 극한의 최대치로 주어진 테스트케이스가 없나? 1, 2가 있는 곳 때문에 실제 벽을 치는 가지수가 훨씬 적나.?.

 

우선 벽을 칠 수 있는 경우의 수를 모두 구한다. (난 재귀로 했다.)

각 경우에 대해 bfs 를 돌려서 바이러스가 다 퍼져나간 상태의 map 을 구한다. 해당 map 의 안전영역 크기(= 0인 곳의 갯수) 를 구한다.

완성된 코드

#include <stdio.h>
#include <vector>
#include <queue>

using namespace std;

vector<vector<int>> map;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
vector<pair<int, int>> two_loc;
int n, m;
int ans = 0;

int bfs(vector<vector<int>> map) {
	queue<pair<int, int>> q;
	int result = 0;
	for(int i = 0; i < two_loc.size(); ++i) {
		q.push(make_pair(two_loc[i].first, two_loc[i].second));
		while(!q.empty()) {
			int cur_x = q.front().first;
			int cur_y = q.front().second;
			q.pop();
			for(int i = 0; i < 4; ++i) {
				int nx = cur_x + dx[i];
				int ny = cur_y + dy[i];
				if (nx < 0 || ny < 0 || nx >= n || ny >= m || map[nx][ny] == 1 || map[nx][ny] == 2) {
					continue;
				} else {
					q.push(make_pair(nx, ny));
					map[nx][ny] = 2;
				}
			}
		}
	}
	// 안전 영역 크기 구하기.
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < m; ++j) {
			if (map[i][j] == 0)
				result++;
		}
	}
	return ans < result ? result : ans;
}

//벽세우기
void partition(int l, vector<vector<int>> map) {
	if (l == 4) {
		// 해당 맵의 안전 영역 크기 구한다.
		ans = bfs(map);
		//printf("maximum = %d\n", ans);
	} else {
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < m; ++j) {
				if (map[i][j] == 0) {
					map[i][j] = 1;
					partition(l + 1, map);
					map[i][j] = 0;
				}
			}
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);

	map.assign(n + 1, vector<int>(m + 1, 0));
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < m; ++j) {
			scanf("%d", &map[i][j]);
			if (map[i][j] == 2) {
				two_loc.push_back(make_pair(i, j));
			}
		}
	}

	partition(1, map);
	printf("%d\n", ans);
}

  

728x90
댓글수0