2020.02.10
Solution
- Input 자료 저장 : inMap을 양쪽으로 2칸씩 여유있게 선언해놓고 4방향을 6(벽)으로 덮어서 만들고 시작했다.
- 알고리즘 : 기본적으로 CCTV의 기준 방향을 완전탐색을 이용해 정하고 방향이 모두 정해졌을 때의 사각지대의 크기를 모두 비교하여 최소 크기를 리턴하는 방식
- getResult 함수 : idx번째부터 끝까지 CCTV의 basis direction을 선택하는 재귀구조의 완전탐색 함수
- getSize 함수 : 방향을 모두 선택한 getResult 함수의 기저조건에서 detectMap에 CCTV탐색을 각 방향과 CCTV의 종류에 따라 탐색하도록 만들었고 탐색이 완료된 후에 사각지대의 크기를 구하고 다시 detectMap을 초기화하여 사각지대의 크기를 return 하는 함수
- detecting 함수 : y,x,dir을 이용해서 탐색하는 구문이 반복적으로 사용되는 것을 간단하게 만들기 위해 기준 좌표로 부터 방향으로 탐색하는 함수
//! 2020.02.10
// TODO BJ15683_감시
#include <cstdio>
#include <vector>
using namespace std;
const int MAX = 15;
const int dx[4] = {1,0,-1,0};
const int dy[4] = {0,-1,0,1};
int N,M;
int inMap[MAX][MAX];
int detectMap[MAX][MAX];
vector <pair<int,int>> CCTV;
vector <int> dirCCTV;
void detecting(int y,int x,int dir){
while(inMap[y][x]!=6){
detectMap[y][x] = 1;
y+=dy[dir];
x+=dx[dir];
}
}
int getSize(){
int cnt = 0;
for(int i=0;i<dirCCTV.size();i++){
int y = CCTV[i].first;
int x = CCTV[i].second;
int numCCTV = inMap[y][x];
switch(numCCTV){
case 1:
detecting(y,x,dirCCTV[i]);
break;
case 2:
detecting(y,x,dirCCTV[i]);
detecting(y,x,dirCCTV[i]+2);
break;
case 3:
for(int dir=0;dir<2;dir++){
int nextDir = (dir+dirCCTV[i])%4;
detecting(y,x,nextDir);
}
break;
case 4:
for(int dir=0;dir<4;dir++){
if(dir==dirCCTV[i]) continue;
detecting(y,x,dir);
}
break;
case 5:
for(int dir=0;dir<4;dir++) detecting(y,x,dir);
break;
}
}
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
if(inMap[i][j]!=6 && detectMap[i][j]==0) cnt++;
detectMap[i][j] = 0;
}
}
return cnt;
}
int getResult(int idx){
if(idx>=dirCCTV.size()){
return getSize();
}
else{
int y = CCTV[idx].first;
int x = CCTV[idx].second;
int numCCTV = inMap[y][x];
int minResult = 987654321;
if(numCCTV==2){
for(int i=0;i<2;i++){
dirCCTV[idx] = i;
int tmp = getResult(idx+1);
if(tmp<minResult) minResult = tmp;
}
}else if(numCCTV==5){
int tmp = getResult(idx+1);
if(tmp<minResult) minResult = tmp;
}else{
for(int i=0;i<4;i++){
dirCCTV[idx] = i;
int tmp = getResult(idx+1);
if(tmp<minResult) minResult = tmp;
}
}
return minResult;
}
}
int main(){
scanf("%d %d",&N,&M);
for(int i=0;i<=N+1;i++){
inMap[i][0] = 6;
inMap[i][M+1] = 6;
}
for(int j=0;j<=M+1;j++){
inMap[0][j] = 6;
inMap[N+1][j] = 6;
}
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
scanf("%d",&inMap[i][j]);
if(inMap[i][j]!=0 && inMap[i][j]!=6){
CCTV.push_back(make_pair(i,j));
dirCCTV.push_back(0);
}
}
}
printf("%d\n",getResult(0));
return 0;
}
실수 : 방향을 넣어주는 for loop에서 같은 변수를 사용하다보니 for loop에 사용되는 변수가 변화하는 문제가 생겼다. 변수관리를 명확히 해줄 필요가 있을 것 같다.
'SW > 알고리즘 문제풀이' 카테고리의 다른 글
BJ12100 2048(Easy) (0) | 2020.02.12 |
---|---|
BJ17142 연구소3 (0) | 2020.02.11 |
BJ13460 구슬탈출2 (0) | 2020.02.10 |
BJ17837 새로운게임2 (0) | 2020.02.09 |
BJ11401 이항계수3 (0) | 2020.02.09 |
Comment