15683監視
質問リンク
コードの説明
監視カメラの種類を入力した後、それぞれの種類の数字をすべて算出する問題です.問題に入る前に、私たちはまず最悪のcaseを計算することに慣れて、完全に探求しているのか、それともタイムアウトしないのかを見てみましょう.
4^8*64で、400万くらいなので、1秒でできます.
次に、各モニタが閲覧できる方向数(便利!)を含む配列を作成します.
rotate_arr[]={4,2,4,4,1};
これは完全プローブにおけるタイプ分岐個数です
find()関数を作成し、壁に遭遇する前にすべてナビゲート(#)する方向をパラメータとして受け入れます.
方向に関数を呼び出す(コード注記を参照)
コード#コード#
#include<iostream>
#include<vector>
using namespace std;
struct CCTV {
int type; //0,1,2,3
int y;
int x;
};
CCTV cctv[8];
int map[8][8];
int answer = 1000;
int N, M;
int K; //CCTV 개수
int rotate_arr[] = { 4,2,4,4,1 }; //type별 총 회전가능 횟수
void find(int dir, CCTV cctv) { // 한방향 모두 탐색하는 함수
dir = dir % 4;
if (dir == 0) {//동쪽 끝까지
for (int i = cctv.x + 1; i < M; i++) {
if (map[cctv.y][i] == 6) break;
map[cctv.y][i] = -1; //-1로 탐색 완료 표시 (#)
}
}
if (dir == 1) { //북쪽
for (int i = cctv.y - 1; i >= 0; i--) {
if (map[i][cctv.x] == 6) break;
map[i][cctv.x] = -1;
}
}
if (dir == 2) { //서쪽
for (int i = cctv.x - 1; i >= 0; i--) {
if (map[cctv.y][i] == 6) break;
map[cctv.y][i] = -1;
}
}
if (dir == 3) { //남쪽
for (int i = cctv.y + 1; i < N; i++) {
if (map[i][cctv.x] == 6) break;
map[i][cctv.x] = -1;
}
}
}
void dfs(int level) {
if (level == K) {
int cnt = 0;//사각지대크기 count
for (int y = 0; y < N; y++) {
for (int x = 0; x < M; x++) {
if (map[y][x] == 0) cnt++;
}
}
answer = min(answer, cnt);
return;
}
int backup[8][8];
int type = cctv[level].type;
for (int i = 0; i < rotate_arr[type]; i++) { //각 cctv type별로 탐색
memcpy(backup, map, sizeof(map)); //map을 backup복사
if (type == 0) { //한방향만 탐색
find(i, cctv[level]);
}
else if (type == 1) {//두방향탐색
find(i, cctv[level]);
find(i+2, cctv[level]);
}
else if (type == 2) { //두방향
find(i, cctv[level]);
find(i+1, cctv[level]);
}
else if (type == 3) { //세방향
find(i, cctv[level]);
find(i + 1, cctv[level]);
find(i + 2, cctv[level]);
}
else if (type == 4) { //네방향
find(i, cctv[level]);
find(i + 1, cctv[level]);
find(i + 2, cctv[level]);
find(i + 3, cctv[level]);
}
dfs(level + 1);
memcpy(map, backup, sizeof(backup)); //탐색완료후 backup-> map복사 (완전탐색을 위해 한단계 탐색이후 돌아올때 그전 map상태 저장)
}
}
int main() {
cin >> N >> M;
for (int y = 0; y < N; y++) {
for (int x = 0; x < M; x++) {
cin >> map[y][x];
if (map[y][x] != 0 && map[y][x] != 6) {
cctv[K].y = y;
cctv[K].x = x;
cctv[K].type = map[y][x] - 1;
K++;
}
}
}
dfs(0);
cout << answer;
return 0;
}
Reference
この問題について(15683監視), 我々は、より多くの情報をここで見つけました https://velog.io/@trevor522/15683-감시テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol