본문 바로가기

ProgramSoliving

백준 : 15683*

반응형

https://www.acmicpc.net/problem/15683

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감시할 수 있는 방법은 다음과 같다. 1번 CCTV는 한 쪽 방향만 감시할 수 있다. 2번과 3번은 두 방향을 감시할 수 있는데, 2번은 감시하는 방향이 서로 반대방향이어야 하고, 3번은 직각 방향이어야 한다. 4번은 세 방향, 5번은 네 방향을 감시할

www.acmicpc.net

 

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int N, M;
int Arr[8][8];
int min_v = 0x7f7f7f;
int vSize = 0;
int dy[4] = { -1,0,1,0 };
int dx[4] = { 0,1,0,-1 };
struct L {
	int y;
	int x;
};
vector <L> buffer;


void Draw(int y, int x, vector<L>& v, int d) {
	while (true) {
		y += dy[d];
		x += dx[d];
		if (y < 0 || x < 0 || y >= N || x >= M) break;
		if (Arr[y][x] == 6) break;
		if (Arr[y][x] != 0) continue;
		v.push_back({ y,x });
		Arr[y][x] = 7;
	}
}

void Clear(vector<L>& v) {
	L b;
	while (!v.empty()) {
		b = v.back();
		v.pop_back();

		Arr[b.y][b.x] = 0;
	}
}

int GetMin() {

	int myMin = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (Arr[i][j] == 0) ++myMin;
		}
	}
	return myMin;
}

void DFS(int seq) {
	if (seq >= vSize) {
		min_v = min(min_v, GetMin());

		return;
	}

	int y = buffer[seq].y;
	int x = buffer[seq].x;
	vector<L> v;

	if (Arr[y][x] == 1) {
		for (int d = 0; d < 4; d++) {
			Draw(y, x, v, d);
			DFS(seq + 1);
			Clear(v);
		}
	}
	else if (Arr[y][x] == 2) {
		for (int d = 0; d < 2; d++) {
			Draw(y, x, v, d);
			Draw(y, x, v, d + 2);
			DFS(seq + 1);
			Clear(v);
		}
	}
	else if (Arr[y][x] == 3) {
		for (int d = 0; d < 4; d++) {
			Draw(y, x, v, d);
			Draw(y, x, v, (d + 1) % 4);
			DFS(seq + 1);
			Clear(v);
		}
	}
	else if (Arr[y][x] == 4) {
		for (int d = 1; d <= 4; d++) {
			Draw(y, x, v, d - 1);
			Draw(y, x, v, d % 4);
			Draw(y, x, v, (d + 1) % 4);
			DFS(seq + 1);
			Clear(v);
		}
	}
	else if (Arr[y][x] == 5) {
		Draw(y, x, v, 0);
		Draw(y, x, v, 1);
		Draw(y, x, v, 2);
		Draw(y, x, v, 3);
		DFS(seq + 1);
		Clear(v);
	}
}


int main(void) {
	cin >> N >> M;

	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < M; ++j) {
			cin >> Arr[i][j];
			if (Arr[i][j] != 0 && Arr[i][j] != 6) {
				buffer.push_back({ i, j });
			}
		}
	}

	vSize = buffer.size();
	DFS(0);
	cout << min_v;

}
반응형

'ProgramSoliving' 카테고리의 다른 글

백준 : 16235  (0) 2020.01.28
백준 : 17140  (0) 2020.01.28
백준 : 13460*  (0) 2020.01.18
백준 : 15685 *  (0) 2020.01.15
백준 : 2565  (0) 2020.01.12