[17142] 연구소 2
풀이
연구소 3 먼저 풀면 연구소 3의 코드를 조금만 고쳐서 통과할 수 있다.
코드
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>
#define MAX 50
using namespace std;
int map[MAX][MAX];
int map2[MAX][MAX];
int n = 0, m = 0;
bool check[MAX][MAX];
vector<pair<int, int> > v;
vector<int> loop;
queue<pair<int, int> > q;
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
int ans = 50000;
void bfs(void) {
int nx = 0, ny = 0;
int t = 3;
while (!q.empty()) {
int qs = q.size();
for (int i = 0; i < qs; i++) {
pair<int, int> curr = q.front(); q.pop();
for (int k = 0; k < 4; k++) {
nx = curr.first + dx[k];
ny = curr.second + dy[k];
if (nx < 0 || nx >= n) continue;
if (ny < 0 || ny >= n) continue;
if (map2[nx][ny] == 0 && check[nx][ny] == false) {
map2[nx][ny] = t;
q.push(make_pair(nx, ny));
check[nx][ny] = true;
}
}
}
t++;
}
}
void printMap(void) {
printf("----------------\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", map2[i][j]);
}
printf("\n");
}
printf("----------------\n");
}
int main(void) {
scanf("%d", &n);
scanf("%d", &m);
int zero = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &map[i][j]);
if (map[i][j] == 2) {
v.push_back(make_pair(i, j));
loop.push_back(0);
}
}
}
//최대 m개까지 활성화 시키기
for (int i = 0; i < m && i < loop.size(); i++) {
loop[i] = 1;
}
//한 번이라도 전체에 퍼질 수 있으면 True
do {
//맵 복사
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
map2[i][j] = map[i][j];
}
}
//방문 초기화
for (int i = 0; i < MAX; i++) {
memset(check[i], false, sizeof(check[i]));
}
//3개 바이러스 선택
for (int i = 0; i < loop.size(); i++) {
if (loop[i] == 1) {
q.push(v[i]);
check[v[i].first][v[i].second] = true;
}
else {
map2[v[i].first][v[i].second] = 0;
}
}
//바이러스 확산
bfs();
//printMap();
//바이러스 체크
bool disperse = true; //모든 빈칸에 바이러스를 퍼뜨릴 수 있으면 true
int curr_ans = 0; //현재 가장 오래걸린 칸
for (int i = 0; i < n && disperse; i++) {
for (int j = 0; j < n && disperse; j++) {
if (map2[i][j] == 0) {
disperse = false;
break;
}
curr_ans = max(curr_ans, map2[i][j]);
}
}
//전부 퍼뜨릴 수 있으면
if (disperse && curr_ans >= 2) {
ans = min(ans, curr_ans - 2);
//printf("ans 갱신 %d\n", ans);
}
} while (prev_permutation(loop.begin(), loop.end()));
//한 번도 전체에 퍼뜨릴 수 없으면
if (ans == 50000) {
printf("-1\n");
}
else {//한 번이라도 전부 퍼뜨릴 수 있으면
printf("%d\n", ans);
}
return 0;
}