728x90
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
이번 문제는 DFS와 브루트 포스를 이용하여 풀 수 있는 문제이다.
실행시간도 2초라 널널할 것 같아 다음과 같이 풀었다.
알고리즘은 다음과 같다.
1. 빈 칸(0) 중 3곳을 골라 벽(1)을 세운다.
2. 벽을 세운 상태에서, 바이러스(2)들을 그래프탐색 시키며 지나간곳을 체크한다.
3. 바이러스가 지나가지 않았고, 벽이 아닌 곳의 수가 가장 큰 값을 구한다.
간단하게 해결할 수 있는 문제이다.
visited[10][10]을 이용하여, 빈 칸은 0 / 벽은 1 / 바이러스가 지나간 곳은 2 로 정하고 코딩하였다.
코드
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define MAX 10
using namespace std;
int n, m;
int res = 0;
int map[MAX][MAX];
// 1: 벽, 2: 바이러스
int visited[MAX][MAX];
vector<pair<int, int>> virus;
vector<pair<int, int>> empties;
int xPos[4] = { -1,0,1,0 };
int yPos[4] = { 0,-1,0,1 };
void init() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
visited[i][j] = map[i][j];
}
}
}
void dfs(int x, int y) {
visited[x][y] = 2;
for (int i = 0; i < 4; i++) {
int movedX = x + xPos[i];
int movedY = y + yPos[i];
if (movedX < 0 || movedY < 0 || movedX >= n || movedY >= m) continue;
if (visited[movedX][movedY] == 0)
dfs(movedX, movedY);
}
}
// 바이러스 순서대로 DFS 진행!
void check() {
for (int i = 0; i < virus.size(); i++) {
dfs(virus[i].first, virus[i].second);
}
// 카운팅하기
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if(visited[i][j] == 0)
cnt++;
}
}
// res에 빈 칸의 수가 가장 클 때를 저장한다.
res = max(res, cnt);
}
void chooseWall(int idx1, int idx2, int idx3) {
pair<int, int> wall1 = empties[idx1];
pair<int, int> wall2 = empties[idx2];
pair<int, int> wall3 = empties[idx3];
visited[wall1.first][wall1.second] = 1;
visited[wall2.first][wall2.second] = 1;
visited[wall3.first][wall3.second] = 1;
// 각 바이러스들을 그래프 탐색 시킨다.
check();
// 체크 완료 후, 원상복구 시킨다.
init();
visited[wall1.first][wall1.second] = 0;
visited[wall2.first][wall2.second] = 0;
visited[wall3.first][wall3.second] = 0;
}
int main() {
int tmp;
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
if (map[i][j] == 0)
empties.push_back(make_pair(i, j));
else if (map[i][j] == 2)
virus.push_back(make_pair(i, j));
}
}
init();
for (int i = 0; i < empties.size()-2; i++) {
for (int j = i+1; j < empties.size()-1; j++) {
for (int k = j+1; k < empties.size(); k++) {
if (i != j && j != k) {
chooseWall(i, j, k);
}
}
}
}
cout << res;
}

728x90
'📊알고리즘 > BOJ' 카테고리의 다른 글
BOJ 14891 - 톱니바퀴 (0) | 2024.03.31 |
---|---|
[시뮬레이션] BOJ 15686 - 치킨 배달 with c++ (0) | 2024.03.24 |
BOJ 2206 - 벽 부수고 이동하기 (0) | 2024.03.05 |
BOJ 1799 - 비숍 (🔄) (0) | 2024.02.29 |
BOJ 16987 - 계란으로 계란치기 (0) | 2024.02.28 |