되면한다
백준 15683. 감시 (백트래킹, 구현) 본문
https://www.acmicpc.net/problem/15683
15683번: 감시
스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감
www.acmicpc.net
감시카메라들이 볼 수 있는 방향들을 모두 탐색해야하므로 백트래킹을 사용했다.
ex. 1번, 2번 감시 카메라가 있는 경우
(1번, 2번) -> (상, 수평), (하, 수평), (좌, 수평), (우, 수평), (상, 수직), (하, 수직), (좌, 수직), (우, 수직)
1. 삽질 포인트
1) left, up 함수 구현:
x와 y값의 근접값부터 -1 표시를 했어야하는데, x와 y를 0부터 -1 표시해서 벽넘어서까지도 -1로 초기화 해버렸다.
2. 특징
1) func함수가 이 문제에 핵심 -> 백트래킹
각 cctv별로 볼 수 있는 곳의 개수가 다르다. 볼 수 있는 곳에 대한 순서열을 만든다.
2) 구현
drawfunc: 순서열이 다 만들어지면, 이에 따라 볼 수 있는 곳을 board에 표시해준다. (board[][] = -1)
countfunc: 볼 수 없는 곳((board[][] == 0) 의 개수를 센다.
3. 코드
#include <iostream>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <tuple>
#include <set>
#include <cstring>
#include <string>
#include <stdio.h>
#include <limits.h>
//#include <bits/stdc++.h>
using namespace std;
int n, m;
int qsize;
int wsize;
int input[10][10];
int board[10][10];
tuple<int, int, int> arr[10];
pair<int, int> ans[10];
pair<int, int> wall[70];
int mn = INT_MAX;
void Right(int x, int y)
{
for(int i = y + 1; i < m; i++)
{
if(board[x][i] == 6)
{
return;
}
else
{
if(board[x][i] <= 5 && board[x][i] >= 1) continue;
board[x][i] = -1;
}
}
}
void Left(int x, int y)
{
for(int i = y-1; i >= 0; i--)
{
if(board[x][i] == 6)
{
return;
}
else
{
if(board[x][i] <= 5 && board[x][i] >= 1) continue;
board[x][i] = -1;
}
}
}
void Up(int x, int y)
{
for(int i = x - 1; i >= 0; i--)
{
if(board[i][y] == 6)
{
return;
}
else
{
if(board[i][y] <= 5 && board[i][y] >= 1) continue;
board[i][y] = -1;
}
}
}
void Down(int x, int y)
{
for(int i = x + 1; i <n; i++)
{
if(board[i][y] == 6)
{
return;
}
else
{
if(board[i][y] <= 5 && board[i][y] >= 1) continue;
board[i][y] = -1;
}
}
}
void drawfunc()
{
//board 초기화
for(int i = 0; i < n; i++)
{
fill(board[i], board[i] + m, 0);
}
for(int i = 0; i < wsize; i++)
{
int x = wall[i].first;
int y = wall[i].second;
board[x][y] = 6;
}
for(int i = 0; i < qsize; i++)
{
int x = get<0>(arr[i]);
int y = get<1>(arr[i]);
board[x][y] = get<2>(arr[i]);
}
for(int i = 0; i < qsize; i++)
{
int cameranum = ans[i].second;
int dir = ans[i].first;
int x = get<0>(arr[i]);
int y = get<1>(arr[i]);
if(cameranum == 1)
{
if(dir == 0) { Right(x, y); }
if(dir == 1) { Left(x, y); }
if(dir == 2) { Up(x, y); }
if(dir == 3){ Down(x, y); }
}
if(cameranum == 2)
{
if(dir == 0) { Right(x, y); Left(x, y);}
if(dir ==1) { Up(x, y); Down(x, y);}
}
if(cameranum == 3)
{
if(dir == 0){ Up(x,y); Right(x, y); }
if(dir == 1) { Right(x, y); Down(x, y);}
if(dir == 2) { Down(x, y); Left(x, y); }
if(dir == 3) { Left(x, y); Up(x, y); }
}
if(cameranum == 4)
{
if(dir == 0){ Left(x, y); Up(x,y); Right(x, y); }
if(dir == 1){ Up(x,y); Right(x, y); Down(x, y); }
if(dir == 2){ Right(x, y); Down(x, y); Left(x, y); }
if(dir == 3){ Down(x, y); Left(x, y); Up(x,y); }
}
if(cameranum == 5){ Right(x, y); Left(x, y); Up(x, y);Down(x, y); }
}
}
void printfunc()
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
cout << board[i][j] << " ";
}
cout << endl;
}
cout << endl;
cout << endl;
}
void countfunc()
{
int cnt = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(board[i][j] == 0) cnt++;
}
}
mn = min(mn, cnt);
}
void func(int cur)
{
if(cur == qsize)
{
// 보드에 그림그리고 0의 개수 세기
drawfunc();
//printfunc();
countfunc();
return;
}
int pointer = 0;
while(1)
{
if(get<2>(arr[cur]) == 1 && pointer >= 4) return;
if(get<2>(arr[cur]) == 2 && pointer >= 2) return;
if(get<2>(arr[cur]) == 3 && pointer >= 4) return;
if(get<2>(arr[cur]) == 4 && pointer >= 4) return;
if(get<2>(arr[cur]) == 5 && pointer >= 1) return;
ans[cur] = make_pair(pointer, get<2>(arr[cur])); // 순서, 카메라 넘버
pointer++;
func(cur + 1);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
int x;
cin >> x;
input[i][j] = x;
if(x >= 1 && x <=5)
{
arr[qsize] = make_tuple(i, j, x);
qsize++;
}
if(x == 6)// 벽
{
wall[wsize] = make_pair(i, j);
wsize++;
}
}
}
func(0);
cout << mn;
}
'코딩테스트준비' 카테고리의 다른 글
백준 3190. 뱀 (구현) (0) | 2023.07.05 |
---|---|
14500. 테트로미노 (구현) (0) | 2023.07.01 |
백준 14499. 주사위 굴리기 (구현) (0) | 2023.07.01 |
백준 15686. 치킨 배달 (구현) (0) | 2023.07.01 |
백준 11559. Puyo Puyo (구현) (0) | 2023.07.01 |
Comments