반응형
14502번 연구소
1. 이해하기
- 연구소에 바이러스가 퍼지지 않도록 벽을 세워야 한다. 벽은 꼭 3개를 세워야 한다.
- 바이러스는 상하좌우로 인접한 빈 칸으로 퍼져나간다.
- 바이러스가 벽으로 인해서 퍼져나갈 수 없는 영역을 안전영역이라 한다. 안전 영역 크기의 최댓값을 구해야 한다.
2. 구현하기
-
바이러스는 상하좌우로 인접한 빈 칸으로 퍼져나간다.
-
BFS를 이용하여 바이러스의 이동을 구현한다.
void bfs(int r, int c) { queue<Point> q; q.push({r,c}); visited[r][c] = true; while(!q.empty()) { int x = q.front().x,y = q.front().y; q.pop(); for(int i = 0; i < 4; i++) { int nx = x+dx[i], ny = y+dy[i]; if(is_out_bound(nx,ny) or visited[nx][ny] or map[nx][ny] == 1) continue; visited[nx][ny] = true; q.push({nx,ny}); } } }
-
-
바이러스가 퍼지지 않도록 3개의 벽을 세우고 그때 안전한 지역이 몇개인지 센다.
int count_safe_area() { int ret = 0; for(int i = 0; i < N; i++) { for(int j = 0; j < M; j++) { if(!visited[i][j] and map[i][j] == 0) ret++; } } return ret; } int solve(int cnt, int index) { if(cnt == 3) { memset(visited,false,sizeof(visited)); for(int i = 0; i < N; i++) { for(int j = 0; j < M; j++) { if(visited[i][j]) continue; if(map[i][j] == 2) { bfs(i,j); } } } return count_safe_area(); } int ret = 0; for(int i = index; i < N*M; i++) { int x = i/M, y = i%M; if(map[x][y] != 0) continue; map[x][y] = 1; ret = max(ret,solve(cnt+1,i+1)); map[x][y] = 0; } return ret; }
3. 전체 코드
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
struct Point{
int x,y;
};
int map[8][8];
bool visited[8][8];
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int N,M;
bool is_out_bound(int x, int y) {
return x < 0 or x >= N or y < 0 or y >= M;
}
void bfs(int r, int c) {
queue<Point> q;
q.push({r,c});
visited[r][c] = true;
while(!q.empty()) {
int x = q.front().x,y = q.front().y; q.pop();
for(int i = 0; i < 4; i++) {
int nx = x+dx[i], ny = y+dy[i];
if(is_out_bound(nx,ny) or visited[nx][ny] or map[nx][ny] == 1) continue;
visited[nx][ny] = true;
q.push({nx,ny});
}
}
}
int count_safe_area() {
int ret = 0;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(!visited[i][j] and map[i][j] == 0) ret++;
}
}
return ret;
}
int solve(int cnt, int index) {
if(cnt == 3) {
memset(visited,false,sizeof(visited));
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(visited[i][j]) continue;
if(map[i][j] == 2) {
bfs(i,j);
}
}
}
return count_safe_area();
}
int ret = 0;
for(int i = index; i < N*M; i++) {
int x = i/M, y = i%M;
if(map[x][y] != 0) continue;
map[x][y] = 1;
ret = max(ret,solve(cnt+1,i+1));
map[x][y] = 0;
}
return ret;
}
int main() {
cin >> N >> M;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
cin >> map[i][j];
}
}
cout << solve(0,0) << '\n';
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 14888번 연산자 끼워넣기 (0) | 2019.10.04 |
---|---|
[백준] 14503번 로봇 청소기 (0) | 2019.10.04 |
[백준] 14501번 퇴사 (0) | 2019.10.03 |
[백준] 14500번 테트로미노 (0) | 2019.10.03 |
[백준] 14499번 주사위 굴리기 (0) | 2019.10.03 |