# 생각
카메라의 방향이 4개이므로 모든 조합을 확인하기 위해 4진법을 이용한다
%= 과 /=을 통해 카메라의 방향을 0,1,2,3의 조합으로 바꿔주어
각 카메라에 대한 func을 수행한다
단, cctv가 0개일 수도 있으므로 첫 입력 때 빈칸의 개수를 저장해준다
# 전체 코드
// 1s, 512MB
// 8 * 8
#include <bits/stdc++.h>
using namespace std;
int dx[4] = { 1,-1,0,0 }, dy[4] = { 0,0,1,-1 };
int n, m, ans;
int coord[8][8];
int camState[8][8];
vector<pair<int, int>> vCamCoord;
// func direction 확인용 출력
void output()
{
cout << '\n';
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cout << camState[i][j] << ' ';
}
cout << '\n';
}
}
void input()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> coord[i][j];
if (coord[i][j] != 0 and coord[i][j] != 6)
{
vCamCoord.push_back({ i,j }); //cctv 좌표 저장
}
if (coord[i][j] == 0) ans++; // cctv가 0개 일수도 있으므로 빈칸 개수 저장
}
}
}
bool OOB(int a, int b)
{
return a < 0 or a >= n or b < 0 or b >= m;
}
// (x,y)에서 dir방향에 있는 빈칸을 모두 7로 변경
void func(int x, int y, int dir)
{
dir %= 4;
while (true)
{
x += dx[dir];
y += dy[dir];
if (OOB(x, y) or camState[x][y] == 6) return; // 범위를 벗어났거나 벽을 만날 때까지
if (camState[x][y] != 0) continue; // 빈칸이 아닐 경우(cctv가 있을 때)
camState[x][y] = 7;
}
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(NULL);
input();
int CCSZ = vCamCoord.size();
// tmp를 4진법으로 구성했을 때 각 자리수는 cctv의 방향
for (int tmp = 0; tmp < (1 << (2 * CCSZ)); tmp++)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
camState[i][j] = coord[i][j];
}
}
int brute = tmp;
for (int i = 0; i < CCSZ; i++)
{
int dir = brute % 4;
brute /= 4;
int x, y;
tie(x, y) = vCamCoord[i];
switch (coord[x][y])
{
case 1:
func(x, y, dir);
break;
case 2: // (0,1), (1,0), (2,3), (3,2)
func(x, y, dir);
if (dir & 1) func(x, y, dir + 3);
else func(x, y, dir + 1);
break;
case 3: // (0,2), (1,3), (2,1), (3,0)
func(x, y, dir);
if (dir <= 1) func(x, y, dir + 2);
else if (dir == 2) func(x, y, dir + 3);
else func(x, y, dir + 1);
break;
case 4:
func(x, y, dir);
func(x, y, dir + 1);
func(x, y, dir + 2);
break;
default:
func(x, y, dir);
func(x, y, dir + 1);
func(x, y, dir + 2);
func(x, y, dir + 3);
break;
}
}
int cnt = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cnt += (camState[i][j] == 0);
}
}
ans = min(ans, cnt);
//output();
}
cout << ans;
}
https://www.acmicpc.net/problem/15683
15683번: 감시
스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감
www.acmicpc.net
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ] 11650_좌표 정렬하기 with cpp (0) | 2022.02.19 |
---|---|
[BOJ] 10814_나이순 정렬 with cpp (0) | 2022.02.18 |
[BOJ] 11328_Strfry with cpp (0) | 2022.02.17 |
[BOJ] 3273_두 수의 합 with cpp (0) | 2022.02.17 |
[BOJ] 10808_알파벳 개수 with cpp (0) | 2022.02.16 |