250x250
Notice
Recent Posts
Recent Comments
Link
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- NIO
- priority_queue
- map
- string
- Java
- set
- List
- spring boot
- dfs
- date
- 힙덤프
- union_find
- sql
- 리소스모니터링
- 스프링부트
- deque
- html
- 스택
- BFS
- 큐
- Union-find
- scanner
- math
- Properties
- javascript
- CSS
- GC로그수집
- alter
- JPA
- Calendar
Archives
- Today
- Total
매일 조금씩
백준 14502번 : 연구소 [C++] 본문
728x90
반응형
BFS와 Brute force를 섞어야하는 문제였다.
Brute force를 공부하기 전이라 관련 포스팅을 참고 하였다.
연구소에 세개의 벽을 세운후 퍼진 바이러스의 영향을 받지 않은 영역의 수의 최댓값을 구하는 문제다.
내 기준 굉장히 까다로운 문제였다..
- 벽과 바이러스가 없는 0인 자리에 벽 3개를 세웠을 때의 모든 경우의 수를 따져야한다. ---> brute force
- 연구소 상태를 복사하여 테스트 할 이차원배열이 따로 필요하다
- 바이러스가 퍼진 후의 연구실 상태를 구하고 그 후, 그때의 0인 자리 수를 세야한다. ---> bfs
- 처음에 예시를 제대로 보지 않아 헷갈렸던 것 ---> 2의 바로 옆에만 벽을 세우는 게 아니다!!! (그래서 brute force)
- 벽을 3개 세워 볼 때마다 나오는 0인 자리 개수는 max로 그때 그때 비교해서 result로 세팅한다.
- 모든 경우의 수가 끝나고 나온 result 값이 0의 자리의 최댓값이 된다.
#include <iostream>
#include <queue>
//#include <cstring> //memset
#include <algorithm>
using namespace std;
const int MAX = 8;
typedef struct
{
int y, x;
}Dir;
Dir moveDir[4] = { { 0, 1 },{ 0, -1 },{ 1, 0 },{ -1, 0 } };
int N, M;
int lab[MAX][MAX];
int temp[MAX][MAX]; // brute force를 위해 연구실 상태를 복사할 곳
int result;
// 벽을 세운후 바이러스가 퍼진 연구실 상태를 구해서 안전한 영역을 센다
void BFS(void) {
int afterSpread[MAX][MAX];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
afterSpread[i][j] = temp[i][j];
}
}
queue<pair<int, int>> q; // y, x
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (afterSpread[i][j] == 2) // 바이러스라면
q.push(make_pair(i, j)); //큐에 넣는다
}
}
while (!q.empty()) {
int y = q.front().first;
int x = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nextY = y + moveDir[i].y;
int nextX = x + moveDir[i].x;
if (0 <= nextY && nextY < N && 0 <= nextX && nextX < M) {
if (afterSpread[nextY][nextX] == 0) //빈칸이라면
{
afterSpread[nextY][nextX] = 2; //바이러스 감염
q.push(make_pair(nextY, nextX));
}
}
}
}
int empty = 0;
// 안전한 영역 세기
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (afterSpread[i][j] == 0)
empty++;
}
}
result = max(result, empty); // 전 것과 비교해 더 큰 걸 result로 함
}
//무작위로 벽을 3개 세우는 함수
void makeWall(int cnt) {
if (cnt == 3) //벽을 세개 만들었으므로
{
BFS(); //안전영역 개수 세기
return;
}
//나머지 벽 두개를 세운다
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (temp[i][j] == 0) {
temp[i][j] = 1; //마찬가지로 해당칸에 세우고
makeWall(cnt + 1);
temp[i][j] = 0; //다시 허문다
}
}
}
}
int main(void) {
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> lab[i][j];
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (lab[i][j] == 0) { //빈칸 발견 시
//연구실 상태를 복사한다
for (int k = 0; k < N; k++) {
for (int l = 0; l < M; l++) {
temp[k][l] = lab[k][l];
}
}
temp[i][j] = 1; //해당 칸에 벽을 세운다
makeWall(1); //벽을 세운 상태이므로 cnt = 1
temp[i][j] = 0; //다시 허문다
}
}
}
cout << result << endl;
return 0;
}
728x90
반응형
'알고리즘 > Graph (DFS, BFS)' 카테고리의 다른 글
백준 2468번 : 안전 영역 [C++] (0) | 2020.08.09 |
---|---|
백준 6603번 : 로또 [C++] (0) | 2020.08.09 |
백준 11724번 : 연결 요소의 개수 [C++] (0) | 2020.08.08 |
백준 1697번 : 숨바꼭질 [C++] (0) | 2020.08.08 |
백준 1012번 : 유기농 배추 [C++] (0) | 2020.08.08 |