[BAEKJOON] 14502번 연구소

2024. 4. 7. 22:00·Algorithm/Brute Force

https://www.acmicpc.net/problem/14502

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크

www.acmicpc.net

문제조건
  1. 벽(1)을 무조건 3개를 세운다.
  2. 벽은 바이러스(2)가 퍼져 나가는걸 막아준다.
  3. 안전영역(0)의 크기가 최댓값은 얼마인가?
접근방법

 

애초에 입력이 8이하로 너무 작아서 진짜 내 맘대로 구현할 수 있는 문제였다.

처음에는 최대한 깔끔하게 로직을 짤 수 없을까란 생각이 계속 들었지만, 그리디도 아니고, 어느 알고리즘도 적용할 수 없었다. 여기에 시간을 좀 많이 쏟은것 같다.

단순하게 문제조건만 맞춘다면 어려울 것 없는 문제다.

안전영역의 크기가 최대가 되기 위해서는 바이러스가 퍼지는 영역이 최소가 되면 된다에 집중해서 풀이했다.

  1.  Brute Force로 벽 3개를 세워서 모든 경우의 수를 생각해줬다.
  2. 각 경우의 수마다 BFS를 바이러스(2)기준으로 수행해서 바이러스가 퍼진 수를 체크하고, 최솟값을 갱신했다.
  3. 물론, 각 경우의 수를 생각해주기 위해 map을 임시로 1로 바꿔줬다가 한번의 경우가 끝나면 0으로 다시 복구시켰다.
  4. 모든 경우를 탐색하고 최소 바이러스수가 나오면 전체 맵에서 0의 개수를 구한다.
0의개수 : 전체맵(n x m) - 벽(1)의 개수 - 최소 바이러스 수
#include <iostream>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;

int n, m, map[9][9], visited[9][9];
int dy[] = { -1, 0, 1, 0 };
int dx[] = { 0, -1, 0, 1 };
int one;
vector<pair<int, int> > v;
vector<pair<int, int> > virus;

//바이러스 퍼져나감
int bfs(int y, int x) {
	int sum = 1;
	queue<pair<int, int> > q;
	q.push({ y,x });
	visited[y][x] = 1;
	while (!q.empty()) {
		int cy = q.front().first;
		int cx = q.front().second;
		q.pop();
		for (int i = 0; i < 4; i++) {
			int ny = cy + dy[i];
			int nx = cx + dx[i];
			if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue;
			if (map[ny][nx] != 1 && !visited[ny][nx]) {
				visited[ny][nx] = 1;
				sum++;
				q.push({ ny,nx });
			}
		}
	}
	return sum;
}

// 0의 개수 세기
int main(){
	cin >> n >> m;
	int res = 100;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> map[i][j];
			if (!map[i][j]) v.push_back({ i,j });
			else if (map[i][j] == 2) virus.push_back({ i,j });
			else if (map[i][j] == 1) one++;
		}
	}
	//벽 3개 세우기
	for (int i = 0; i < v.size(); i++) {
		for (int j = 0; j < i; j++) {
			for (int k = 0; k < j; k++) {
				int cnt = 0;
				map[v[i].first][v[i].second] = map[v[j].first][v[j].second] = map[v[k].first][v[k].second] = 1;
				for (int spread = 0; spread < virus.size(); spread++) {
					if(!visited[virus[spread].first][virus[spread].second])
						cnt += bfs(virus[spread].first, virus[spread].second);
				}
				res = min(res, cnt);
				memset(visited, 0, sizeof(visited));
				map[v[i].first][v[i].second] = map[v[j].first][v[j].second] = map[v[k].first][v[k].second] = 0;
			}
		}
	}
	cout << n*m - (one+3) - res;
}

 

for문 중첩이 엄청 심한데 어디까지나 이 문제의 입력이 엄청나게 작다는 걸 생각하고, 좀 더 좋은 로직을 짜도록 노력하자,,!! 근데 이번 문제는 전체 탐색을 어떻게 하지라는 부분을 가장 많이 고민했다,,,

'Algorithm > Brute Force' 카테고리의 다른 글

[BAEKJOON] 14500번 테트로미노  (1) 2024.04.06
[BAEKJOON] 7568번 덩치  (0) 2024.03.20
[BAEKJOON] 1057번 토너먼트  (0) 2024.03.06
'Algorithm/Brute Force' 카테고리의 다른 글
  • [BAEKJOON] 14500번 테트로미노
  • [BAEKJOON] 7568번 덩치
  • [BAEKJOON] 1057번 토너먼트
Ls._.Rain
Ls._.Rain
안되면 될때까지 삽질했던 기록
  • Ls._.Rain
    Ls{Diary}
    Ls._.Rain
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • Github (2)
      • Spring (51)
        • Batch Programming (13)
        • 결제 (4)
        • 대용량 트래픽 (32)
        • OpenAI (0)
        • Security (0)
        • WebSocket (0)
        • JPA (1)
      • Algorithm (67)
        • DFS (6)
        • BFS (6)
        • Dynamic Programming (10)
        • Brute Force (4)
        • Binary Search (6)
        • 구현, 시뮬레이션 (15)
        • Stack (1)
        • Greedy (4)
        • Priority_Queue (2)
        • Back Tracking (3)
        • Geometry (2)
        • SCC (1)
        • 투포인터 (4)
        • 최대유량 (1)
        • 정렬 (1)
      • OS (0)
      • DevOps (15)
        • AWS (11)
        • Docker (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • hELLO· Designed By정상우.v4.10.0
Ls._.Rain
[BAEKJOON] 14502번 연구소
상단으로

티스토리툴바