Memo
로직 설명
•
벽 3개를 세울 수 있는 모든 경우를 조사합니다.
•
벽 3개가 세워지면, 바이러스 위치를 큐에 넣고 BFS를 돌립니다.
어려웠던 부분
•
브루트포스를 돌릴 때, 인자로 x,y 좌표를 넘기지 않고, 몇 번째 위치인지를 넘겼습니다. 위치를 받고나서, x,y 좌표를 구해냈습니다.
•
좌표를 구해내는 과정에서 맵의 시작 위치가 0,0이 아닌 1,1부터 시작해서 어려웠기 때문에, 0,0을 시작 위치로 바꿔서 풀었습니다.
•
브루트포스 함수 내에서
if (cnt == 3)
{
bfs();
safe_area_check();
return ;
}
if (ind >= N * M)
return ;
Python
복사
if문 순서를 잘못 고려했습니다. 처음에는 if (ind ≥ N * M) 이 부분이 위에 있었는데, 그럴 경우 마지막 위치에 기둥을 세웠을 경우 BFS를 돌리지 않고 종료되는 문제가 있었습니다.
Code
제출 날짜
@5/15/2021
메모리
2016 KB
시간
44 ms
#include <iostream>
#include <queue>
#include <cstring>
int N, M;
int g_map[9][9];
int cp_map[9][9];
std::queue<std::pair<int, int> >q;
int dy[4] = {0,0,1,-1};
int dx[4] = {1,-1,0,0};
int ans = 0;
void io_faster()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
}
void input()
{
io_faster();
std::cin >> N >> M;
for (int i = 0 ; i < N ; i++)
for (int j = 0 ; j < M ; j++)
std::cin >> g_map[i][j];
}
void bfs()
{
int qy, qx, ny, nx;
std::memcpy(cp_map, g_map, sizeof(g_map));
for (int i = 0 ; i < N ; i++)
for (int j = 0 ; j < M ; j++)
if (g_map[i][j] == 2)
q.push({i, j});
while (!q.empty())
{
qy = q.front().first;
qx = q.front().second;
q.pop();
for (int i = 0 ; i < 4 ; i++)
{
ny = qy + dy[i];
nx = qx + dx[i];
if (ny < 0 || ny >= N || nx < 0 || nx >= M || cp_map[ny][nx])
continue;
cp_map[ny][nx] = 2;
q.push({ny,nx});
}
}
}
void safe_area_check()
{
int cnt = 0;
for (int i = 0 ; i < N ; i++)
for (int j = 0 ; j < M ; j++)
if (!cp_map[i][j])
cnt++;
if (ans < cnt)
ans = cnt;
}
void brute_force(int ind, int cnt)
{
int y, x;
if (cnt == 3)
{
bfs();
safe_area_check();
return ;
}
if (ind >= N * M)
return ;
for (int i = ind ; i < N * M ; i++)
{
x = i % M;
y = i / M;
if (!g_map[y][x])
{
g_map[y][x] = 1;
brute_force(i + 1, cnt + 1);
g_map[y][x] = 0;
}
}
}
void solve()
{
brute_force(0, 0);
}
void print_val()
{
std::cout << ans;
}
int main()
{
input();
solve();
print_val();
return (0);
}
C++
복사