티스토리 뷰
#include <bits/stdc++.h>
#define Q q.front()
using namespace std;
int V[4] = {-1, 0, 1, 0};
int H[4] = {0, 1, 0, -1};
int n, m, zero = -3; //벽 3개를 무조건 설치하므로 -3으로 시작합니다.
int Max = 0;
int Map[8][8] = {};
vector<pair<int, int> > two;
void bfs(void) { //bfs
queue<pair<int, int> > q; //큐
int cnt = zero; //벽 3개를 설치한 이후 0의 개수
bool v[n][m]; //방문 확인 배열
memset(v, false, sizeof(bool)*n*m); //방문 확인
for(pair<int, int> i : two) q.push({i.first, i.second}); //바이러스인 곳을 전부 큐에 집어 넣고
while(!q.empty()) { //bfs 실행
int x = get<0>(Q);
int y = get<1>(Q);
q.pop();
for(int j=0; j<4; j++) {
x += V[j];
y += H[j];
if(x >= 0 && y >= 0 && x < n && y < m && Map[x][y]==0 && !v[x][y]) { //방문을 하지 않았으며 0인 곳이라면
v[x][y] = true;
--cnt;
q.push({x, y});
}
x -= V[j];
y -= H[j];
}
}
if(Max < cnt) Max = cnt; //최대값보다 cnt이 크다면 cnt을 대입
}
//벽 설치하기
void loop(int N, int a, int b) { //브루트포스, N은 벽 설치한 개수, a와 b는 최근 설치한 벽의 위치 입니다.
if(N == 3) { //세 개 설치한 경우
bfs(); //bfs
return;
}
for(int i=a; i<n; i++) { //벽 설치하기
int j=0;
if(N > 0 && i == a) j = b+1; //이전 벽보다 오른쪽으로
for(j; j<m; j++) {
if(Map[i][j] == 0) { //0인 곳에만 벽을 칠 수 있습니다.
Map[i][j] = 1; //벽을 칩니다.
if(N<3) loop(N+1, i, j); //새로운 벽을 치기
Map[i][j] = 0; //벽을 다시 치웁니다 (다른 곳에 설치하기 위해)
}
}
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
int tmp = 0;
cin >> tmp;
Map[i][j] = tmp;
if(tmp == 2) two.push_back({i, j});
else if(tmp == 0) ++zero; //0의 개수 구하기
}
loop(0, 0, 0); //브루트포스 실행
cout << Max;
}
풀이 : BFS + 브루트포스
들어가기 전에
using namespace std;
을 하게 되면 전역변수를 만들 때, max, map 같은 건 이미 std에 있는 것들이다 보니 이름을 다르게 해야합니다.
1. 브루트포스로 벽을 설치할 3 곳을 1로 바꾸어 줍니다. 중요한 점은 시간을 아끼기 위해서 처음 설치한 벽 보다 두번째로 설치한 벽은 더 오른쪽이나 아래에 있어야 하며, 두번째로 설치한 벽보다 세번째로 설치한 벽이 더 오른쪽이나 아래에 있어야 합니다.
void loop(int N, int a, int b) {
if(N == 3) {
bfs();
return;
}
for(int i=a; i<n; i++) {
int j=0;
if(N > 0 && i == a) j = b+1;
for(j; j<m; j++) {
if(Map[i][j] == 0) {
Map[i][j] = 1;
if(N<3) loop(N+1, i, j);
Map[i][j] = 0;
}
}
}
}
이를 위해서 2중 for문에 약간의 조건문을 추가 했으며
벽을 세번 설치한 이후 bfs을 실행하도록 만들었습니다. //if(N == 3)
2. 큐에 2인 곳을 전부 다 넣은 다음 bfs을 돌려서 0의 개수를 구합니다.
3. 1, 2 을 반복하면서 0의 개수의 최대값을 구합니다.
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
'c++ > BAEKJOON' 카테고리의 다른 글
c++ 15681번 트리와 쿼리 (백준) (0) | 2023.11.26 |
---|---|
C++ 17142번 연구소 3 (백준) (0) | 2023.11.17 |
c++ 1240번 노드사이의 거리 (백준) (0) | 2023.10.24 |
c++ 2206 벽 부수고 이동하기 (백준) (0) | 2023.10.14 |
c++ 14226번 이모티콘 (백준) (0) | 2023.10.06 |
- Total
- Today
- Yesterday
- Lazy Propagation
- java
- DFS
- 누적합
- DP
- 누적 합
- 그래프
- 그리디
- XOR
- 1835번
- 정렬
- 최대공약수
- 1835
- 오프라인 쿼리
- C언어
- PASCAL
- 덱
- C++
- 스택
- 브루트포스
- Krustal
- find
- union
- 백준
- 세그먼트 트리
- 최소 스패닝 트리
- 플로이드
- Segment Tree
- BFS
- 기하학
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |