알고리즘
백준 14502번 연구소 C++
영춘권의달인
2021. 12. 28. 12:33
백트래킹을 이용하여 벽을 3개를 세운 모든 경우를 구하고 각 경우마다 bfs를 통해 바이러스가 퍼지는 것을 시뮬레이션 한 뒤, 그 중 안전지대가 가장 많이 나온 경우를 출력하였다.
#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
int n, m;
vector<vector<int>> v(8, vector<int>(8, 0));
vector<vector<bool>> visited(8, vector<bool>(8, false));
int ans = -1;
int wall = 3;
int posR[4] = { -1,0,1,0 };
int posC[4] = { 0,1,0,-1 };
void BT(int index, int cnt);
int bfs();
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> v[i][j];
if (v[i][j] == 1) wall++;
}
}
BT(0, 0);
cout << ans;
};
void BT(int index, int cnt) {
if (index >= n * m) return;
if (cnt == 3) {
ans = max(ans, bfs());
return;
}
for (int i = index; i < n * m; i++) {
int row = i / m;
int col = i % m;
if (v[row][col] == 0) {
v[row][col] = 1;
BT(index + 1, cnt + 1);
v[row][col] = 0;
}
}
}
int bfs() {
int tmp[8][8];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
visited[i][j] = false;
tmp[i][j] = v[i][j];
}
}
int cnt = n * m - wall;
queue<pair<int, int>> q;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (tmp[i][j] == 2 && !visited[i][j]) {
cnt--;
q.push({ i,j });
visited[i][j] = true;
while (!q.empty()) {
auto curr = q.front();
q.pop();
for (int k = 0; k < 4; k++) {
int nextRow = curr.first + posR[k];
int nextCol = curr.second + posC[k];
if (nextRow < 0 || nextRow >= n) continue;
if (nextCol < 0 || nextCol >= m) continue;
if (tmp[nextRow][nextCol] == 1) continue;
if (visited[nextRow][nextCol]) continue;
tmp[nextRow][nextCol] = 2;
q.push({ nextRow, nextCol });
visited[nextRow][nextCol] = true;
cnt--;
}
}
}
}
}
return cnt;
}