예제 입력 1
7 7
2 0 0 0 1 1 0
0 0 1 0 1 2 0
0 1 1 0 1 0 0
0 1 0 0 0 0 0
0 0 0 0 0 1 1
0 1 0 0 0 0 0
0 1 0 0 0 0 0
예제 출력 1
27
예제 입력 2
4 6
0 0 0 0 0 0
1 0 0 0 0 2
1 1 1 0 0 2
0 0 0 0 0 2
예제 출력 2
9
예제 입력 3
8 8
2 0 0 0 0 0 0 2
2 0 0 0 0 0 0 2
2 0 0 0 0 0 0 2
2 0 0 0 0 0 0 2
2 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
예제 출력 3
3
https://www.acmicpc.net/problem/14502
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크기가 N×M인 직사각형으로 나타낼 수 있으며, 직사각형은 1×1 크기의 정사각형으로 나누어져 있다. 연구소는 빈 칸, 벽으로 이루어져 있으며, 벽은 칸 하나를 가득 차지한다. 일부 칸은 바이러스가 존재하며, 이 바이러스는 상하좌우로 인접한 빈 칸으로 모두 퍼져나갈 수 있다.
www.acmicpc.net
- 벽을 세우는 내용을 제외하면, 시간 복잡도는 O(NM)
- 벽을 세우는 시간 복잡도는 O(NM^3)
- 총 시간복잡도는 O(NM^4) 가 되는데, N과 M의 최대값이 8이므로 가능하다.
- 세운 3개의 벽의 위치(a,b,c)중 중복이 있으면 안되는데, b루프에서 a와의 중복을 체크하고 c루프에서 b와의 중복을 처리하는 식으로 구현했는데, 그럴 경우 a와 c가 중복인 경우를 처리하지 못해서 헤맸었음.
#include <stdio.h>
constexpr int MAX_SIZE = 9;
constexpr int MAX_QUEUE_SIZE = 1000;
int R, C;
int dR[4] = { -1, 1, 0, 0 };
int dC[4] = { 0, 0, -1, 1 };
inline int MAX(int a, int b)
{
return a > b ? a : b;
}
enum Const
{
EMPTY,
WALL,
VIRUS
};
class Point
{
public:
int r;
int c;
Point() { r = c = 0; }
Point(int r, int c) : r(r), c(c) {}
bool IsInBoundary()
{
return (r >= 0) && (r < R) && (c >= 0) && (c < C);
}
};
class MapClass
{
public:
int map[MAX_SIZE][MAX_SIZE];
};
MapClass m;
template <typename T>
class Queue
{
private:
int front;
int rear;
T data[MAX_QUEUE_SIZE];
public:
Queue() { front = rear = 0; }
void push(T item)
{
data[rear] = item;
rear = (rear + 1) % MAX_QUEUE_SIZE;
}
T pop()
{
T result = data[front];
front = (front + 1) % MAX_QUEUE_SIZE;
return result;
}
bool IsEmpty() { return front == rear; }
void Reset()
{
front = rear = 0;
}
};
Queue<Point> q;
int go(MapClass m, Queue<Point> q)
{
while (!q.IsEmpty())
{
Point now = q.pop();
for (int i = 0; i < 4; i++)
{
Point next(now.r + dR[i], now.c + dC[i]);
if (!next.IsInBoundary()) continue;
if (m.map[next.r][next.c] != Const::EMPTY) continue;
m.map[next.r][next.c] = Const::VIRUS;
q.push(next);
}
}
int result = 0;
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (m.map[i][j] == Const::EMPTY) result++;
}
}
return result;
}
int main(void)
{
int result = 0;
scanf("%d %d", &R, &C);
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
scanf("%d", &m.map[i][j]);
if (m.map[i][j] == Const::VIRUS)
{
Point p(i, j);
q.push(p);
}
}
}
for (int aR = 0; aR < R; aR++)
{
for (int aC = 0; aC < C; aC++)
{
if (m.map[aR][aC] != Const::EMPTY) continue;
for (int bR = 0; bR < R; bR++)
{
for (int bC = 0; bC < C; bC++)
{
if (m.map[bR][bC] != Const::EMPTY) continue;
for (int cR = 0; cR < R; cR++)
{
for (int cC = 0; cC < C; cC++)
{
if (m.map[cR][cC] != Const::EMPTY) continue;
if (aR == bR && aC == bC) continue;
if (bR == cR && bC == cC) continue;
if (aR == cR && aC == cC) continue;
m.map[aR][aC] = Const::WALL;
m.map[bR][bC] = Const::WALL;
m.map[cR][cC] = Const::WALL;
result = MAX(result, go(m, q));
m.map[aR][aC] = Const::EMPTY;
m.map[bR][bC] = Const::EMPTY;
m.map[cR][cC] = Const::EMPTY;
}
}
}
}
}
}
printf("%d\n", result);
return 0;
}
'Algorithm > 문제풀이' 카테고리의 다른 글
[BFS] 벽 부수고 이동하기 (0) | 2019.10.15 |
---|---|
[BFS] 돌 그룹 (0) | 2019.10.15 |
[BFS] 데스 나이트 (0) | 2019.10.14 |
[BFS] 뱀과 사다리 게임 (0) | 2019.10.14 |
★ [Brute Force - 비트마스크] 2048 (Easy) (0) | 2019.10.09 |