[BOJ 14502] 연구소

문제 요약

  • N×M 격자에 벽 3개 세워서 바이러스 확산 막기
  • (이미 벽도 좀 세워져 있음)
  • 안전 영역 최대화

접근

빈 칸 중 3개 골라서 벽 세우고 BFS로 바이러스 퍼뜨린 뒤 안전 영역 계산. 경우의 수가 크지 않아서 브루트포스로 충분했음.

3 <= N, M <= 8 : 범위

핵심 로직

  • 빈 칸 목록 따로 저장해두고 3중 for문으로 조합
  • 매 조합마다 grid 복사해서 BFS
  • 안전 영역 = 전체 - 벽(초기 + 3) - 바이러스(초기+확산)

실수 or 배운 점

  • 거의 다 했는데 3개 조합 뽑는게 애매했다. 결국 빈칸좌표를 미리 vector에 저장해서 뽑으니까 깔끔했고, 백트래킹까지 하니까 보기 좋더라.

코드

// Online C++ Compiler - Build, Compile and Run your C++ programs online in your favorite browser
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int N, M;
    int maxArea = 0;
    cin >> N >> M;
    vector<vector<int>> arr(N, vector<int>(M, 0));
    vector<pair<int, int>> v;
    vector<pair<int, int>> e;
    int wallCnt = 0;
    int vCnt = 0;
    
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            int temp;
            cin >> temp;
            arr[i][j] = temp;
            if(temp == 2){
                v.push_back({i,j});
                vCnt++;
            }
            else if(temp == 1) wallCnt++;
            else{
                e.push_back({i, j});
            }
        }
    }
    
    
    
    
    int K = e.size();
    //pick 3
    for (int i = 0; i < K; ++i) {
        for (int j = i + 1; j < K; ++j) {
            for (int k = j + 1; k < K; ++k) {
                // wall
                arr[e[i].first][e[i].second] = 1;
                arr[e[j].first][e[j].second] = 1;
                arr[e[k].first][e[k].second] = 1;
    
                
    
                queue<pair<int, int>> q;
                int vCnt2 = 0;
                for(auto vv : v){
                    q.push(vv);
                }
                auto tempArr = arr;
                //start spread
                while(!q.empty()){
                    auto [y, x] = q.front(); q.pop();
                    int dx[] = {-1, 1, 0, 0}; int dy[] = {0, 0, -1, 1};
                    
                    for(int m = 0; m < 4; m++){
                        int ny = y + dy[m]; int nx = x + dx[m];
                        if(0 <= nx && nx < M && 0 <= ny && ny < N && tempArr[ny][nx] != 2 && tempArr[ny][nx] != 1) {
                            q.push({ny, nx});
                            tempArr[ny][nx] = 2;
                            vCnt2++;
                        }
                    }
                    
                }
                
                maxArea = max((N*M - (wallCnt+3) - (vCnt+vCnt2)), maxArea);
                // fuck wall
                arr[e[i].first][e[i].second] = 0;
                arr[e[j].first][e[j].second] = 0;
                arr[e[k].first][e[k].second] = 0;
            }
        }
    }
    
    cout << maxArea;
   
    
    
    
    return 0;
}