728x90

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

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감��

www.acmicpc.net

조합(combination)으로 일단 각 cctv의 방향을 정해주었고 그 다음에 cctv가 감시할 수 있는 영역을 -1로 표시해주었다. 감시할 수 있는 영역을 표시해주는 것은 spread라는 함수를 만들어서 표시해줄 수 있도록 했다. 

이것도 완전 노가다 문제였다.

#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;

int numOfCctv;
vector<char> cctv[6]; //1~5만 씀
int minSquare = 64;
vector<pair<int, int>> cctvLocation;
vector<int> cctvInfo;
vector<vector<int>> v;
int n, m;

void spread(vector<vector<int>>& office, int row, int col, char c) {
	if (c == 'e') {
		while (true) {
			if (col + 1 < m && office[row][++col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
	else if (c == 'w') {
		while (true) {
			if (col - 1 >= 0 && office[row][--col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
	else if (c == 's') {
		while (true) {
			if (row + 1 < n && office[++row][col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
	else if (c == 'n') {
		while (true) {
			if (row - 1 >= 0 && office[--row][col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
}

int getArea(vector<char> result) {
	vector<vector<int>> office(n, vector<int>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			office[i][j] = v[i][j];
		}
	}
	for (int i = 0; i < result.size(); i++) {
		int row = cctvLocation[i].first;
		int col = cctvLocation[i].second;
		if (cctvInfo[i] == 1) {
			spread(office, row, col, result[i]);
		}
		else if (cctvInfo[i] == 2) {
			if (result[i] == 'h') {
				spread(office, row, col, 'e');
				spread(office, row, col, 'w');
			}
			else if (result[i] == 'v') {
				spread(office, row, col, 's');
				spread(office, row, col, 'n');
			}
		}
		else if (cctvInfo[i] == 3) {
			if (result[i] == 'e') {
				spread(office, row, col, 'e');
				spread(office, row, col, 's');
			}
			else if (result[i] == 'w') {
				spread(office, row, col, 'w');
				spread(office, row, col, 'n');
			}
			else if (result[i] == 's') {
				spread(office, row, col, 's');
				spread(office, row, col, 'w');
			}
			else if (result[i] == 'n') {
				spread(office, row, col, 'n');
				spread(office, row, col, 'e');
			}
		}
		else if (cctvInfo[i] == 4) {
			if (result[i] == 'e') {
				spread(office, row, col, 'n');
				spread(office, row, col, 'e');
				spread(office, row, col, 's');
			}
			else if (result[i] == 'w') {
				spread(office, row, col, 's');
				spread(office, row, col, 'w');
				spread(office, row, col, 'n');
			}
			else if (result[i] == 's') {
				spread(office, row, col, 'e');
				spread(office, row, col, 's');
				spread(office, row, col, 'w');
			}
			else if (result[i] == 'n') {
				spread(office, row, col, 'w');
				spread(office, row, col, 'n');
				spread(office, row, col, 'e');
			}
		}
		else if (cctvInfo[i] == 5) {
			spread(office, row, col, 'w');
			spread(office, row, col, 'n');
			spread(office, row, col, 'e');
			spread(office, row, col, 's');
		}
	}

	int countZero = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (office[i][j] == 0)
				countZero++;
		}
	}
	return countZero;
}

void combination(vector<char> result, int num) {
	if (num == numOfCctv) {
		int area = getArea(result);
		if (area < minSquare)
			minSquare = area;
		return;
	}
	if (cctvInfo[num] == 1) {
		for (int i = 0; i < cctv[1].size(); i++) {
			result[num] = cctv[1][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 2) {
		for (int i = 0; i < cctv[2].size(); i++) {
			result[num] = cctv[2][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 3) {
		for (int i = 0; i < cctv[3].size(); i++) {
			result[num] = cctv[3][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 4) {
		for (int i = 0; i < cctv[4].size(); i++) {
			result[num] = cctv[4][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 5) {
		result[num] = 'a';
		combination(result, num + 1);
	}
}

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	cctv[1] = {'e', 'w', 's', 'n'};
	cctv[2] = { 'h', 'v' }; //horizontal, vertical
	cctv[3] = { 'e', 'w', 's', 'n' };
	cctv[4] = { 'e', 'w', 's', 'n' };
	cctv[5] = { 'a' };
	cin >> n >> m;
	v = vector<vector<int>>(n, vector<int>(m));
	int temp;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> temp;
			v[i][j] = temp;
			if (temp != 0 && temp != 6) {
				numOfCctv++;
				cctvLocation.push_back(make_pair(i, j));
				cctvInfo.push_back(temp);
			}
		}
	}
	combination(vector<char>(numOfCctv), 0);
	cout << minSquare;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 10819번 차이를 최대로  (0) 2020.08.31
[백준] 1987번 알파벳  (0) 2020.08.30
[백준] 15686 치킨 배달  (0) 2020.08.30
[백준] 2636 치즈  (0) 2020.08.29
[백준] 2668번 숫자고르기  (0) 2020.08.29

+ Recent posts