그냥 1차원적인 구현 문제이다.
감시카메라의 갯수가 8개를 넘지않으므로
각 카메라에 대한 회전 경우의수 4가지 (0도 90도 180도 270도)
4^8 = O(65536 * n^2(사각지역을 구할때 8*8밖에 되지않아 그냥 0인곳을 매번 다 탐색했다))
본인은 구현하지 않았지만 생각해보면 다음 5번 경우는 회전을해도 그대로니
<code>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | //pda_pro12 #include<iostream> #include<vector> #define INT 0x7fff0000 using namespace std; int dx[] = { -1,0,1,0 }, dy[] = { 0,1,0,-1 }, n, m; // 0: 위 // 1: 오른 // 2: 아래 // 3: 왼 bool Map[9][9][4]; int tmp[9][9], Orign[9][9]; vector<pair<int, int>> v; // 감시카메라의 좌표정보 저장(1~8) vector<int> Rotate; // 카메라 회전정보 저장(O(4^v.size())) int ans = INT; // 최소값 산출을 위해 초기값 INT MAX값으로 214748347 설정 int Min(int a, int b) { return (a < b) ? a : b; } int Recovery() { // 감시처리 전의 상태로 복구함과 동시에 사각지역 탐색 int cnt = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (tmp[i][j] == 0) cnt++; tmp[i][j] = Orign[i][j]; } } return cnt; } void View_Camera(int num, int flag) { // 몇번 카메라가 몇도 회전 했는지 Prameter로 받는다. int x = v[num].first; int y = v[num].second; for (int i = 0; i < 4; i++) { if (Map[x][y][i]) { int nx = x + dx[(i + flag) % 4]; int ny = y + dy[(i + flag) % 4]; while (tmp[nx][ny] != 6 && nx >= 0 && nx < n && ny >= 0 && ny < m) { // 범위를 벗어나지 않거나 이미 감시한 지역(9)이고, 빈칸일경우 if (tmp[nx][ny] == 0) tmp[nx][ny] = 9; nx += dx[(i + flag) % 4]; ny += dy[(i + flag) % 4]; } } } return; } void dfs(int cnt) { if (cnt == v.size()) { // 카메라에 대한 회전 정보가 카메라 갯수와 같아젔다면 for (int i = 0; i < Rotate.size(); i++) // 회전정보만큼 카메라 돌려서 감시지역 처리해주기 View_Camera(i, Rotate[i]); ans = Min(ans, Recovery()); return; } for (int i = 0; i < 4; i++) { // 0: No rotate 1: 90 2: 180 3: 270 Rotate.push_back(i); dfs(cnt + 1); Rotate.pop_back(); } return; } int main() { cin >> n >> m; // n = row , m = col for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> tmp[i][j]; Orign[i][j] = tmp[i][j]; if (!tmp[i][j] || tmp[i][j] == 6) continue; // 0이나 벽일경우 v.push_back(make_pair(i, j)); // Camera Direction (row, col); switch (tmp[i][j]) { // No1 ~ No5 Camera Direction input case 1: // 1type Camera --> 초기 방향에 대한 정보를 저장해둔다 Map[i][j][1] = true; break; case 2: //2type Camera Map[i][j][1] = true; Map[i][j][3] = true; break; case 3: // 3type Camera Map[i][j][0] = true; Map[i][j][1] = true; break; case 4: // 4type Camera Map[i][j][0] = true; Map[i][j][1] = true; Map[i][j][3] = true; break; case 5: for (int a = 0; a < 4; a++) Map[i][j][a] = true; break; } } } dfs(0); cout << ans; return 0; } |
< STL의 유혹을 떨처버린 Code >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | //pda_pro12 #include<iostream> #define INT 0x7fff0000 using namespace std; int dx[] = { -1,0,1,0 }, dy[] = { 0,1,0,-1 }, n, m; // 0: 위 // 1: 오른 // 2: 아래 // 3: 왼 bool Map[9][9][4]; int tmp[9][9], Orign[9][9]; template<class T> class _vector { public: int _size; int capacity; T* arr; _vector() { _size = 0; capacity = 32; arr = new T[capacity]; } _vector(int k) { _size = k; capacity = k; arr = new T[k]; } ~_vector() { delete[] arr; } void clear() { delete[] arr; _size = 0; capacity = 32; arr = new T[capacity]; } void resize(int k) { T* temp; temp = new T[k]; for (int i = 0; i < _size; ++i) temp[i] = arr[i]; delete[] arr; arr = temp; _size = capacity = k; } int size() const { return _size; } T* begin() const { return &arr[0]; } T* end() const { return &arr[0] + _size; } void push_back(T val) { if (capacity == _size) { resize(_size * 2); _size /= 2; } arr[_size++] = val; } void pop_back() { _size--; } T& operator[](int idx) { return arr[idx]; } T operator[](int idx) const{ return arr[idx]; } }; _vector<pair<int, int>> v; // 감시카메라의 좌표정보 저장(1~8) _vector<int> Rotate; // 카메라 회전정보 저장(O(4^v.size())) int ans = INT; // 최소값 산출을 위해 초기값 INT MAX값으로 214748347 설정 int Min(int a, int b) { return (a < b) ? a : b; } int Recovery() { // 감시처리 전의 상태로 복구함과 동시에 사각지역 탐색 int cnt = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (tmp[i][j] == 0) cnt++; tmp[i][j] = Orign[i][j]; } } return cnt; } void View_Camera(int num, int flag) { // 몇번 카메라가 몇도 회전 했는지 Prameter로 받는다. int x = v[num].first; int y = v[num].second; for (int i = 0; i < 4; i++) { if (Map[x][y][i]) { int nx = x + dx[(i + flag) % 4]; int ny = y + dy[(i + flag) % 4]; while (tmp[nx][ny] != 6 && nx >= 0 && nx < n && ny >= 0 && ny < m) { // 범위를 벗어나지 않거나 이미 감시한 지역(9)이고, 빈칸일경우 if (tmp[nx][ny] == 0) tmp[nx][ny] = 9; nx += dx[(i + flag) % 4]; ny += dy[(i + flag) % 4]; } } } return; } void dfs(int cnt) { if (cnt == v.size()) { // 카메라에 대한 회전 정보가 카메라 갯수와 같아젔다면 for (int i = 0; i < Rotate.size(); i++) // 회전정보만큼 카메라 돌려서 감시지역 처리해주기 View_Camera(i, Rotate[i]); ans = Min(ans, Recovery()); return; } for (int i = 0; i < 4; i++) { // 0: No rotate 1: 90 2: 180 3: 270 Rotate.push_back(i); dfs(cnt + 1); Rotate.pop_back(); } return; } int main() { cin >> n >> m; // n = row , m = col for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> tmp[i][j]; Orign[i][j] = tmp[i][j]; if (!tmp[i][j] || tmp[i][j] == 6) continue; // 0이나 벽일경우 v.push_back(make_pair(i, j)); // Camera Direction (row, col); switch (tmp[i][j]) { // No1 ~ No5 Camera Direction input case 1: // 1type Camera --> 초기 방향에 대한 정보를 저장해둔다 Map[i][j][1] = true; break; case 2: //2type Camera Map[i][j][1] = true; Map[i][j][3] = true; break; case 3: // 3type Camera Map[i][j][0] = true; Map[i][j][1] = true; break; case 4: // 4type Camera Map[i][j][0] = true; Map[i][j][1] = true; Map[i][j][3] = true; break; case 5: for (int a = 0; a < 4; a++) Map[i][j][a] = true; break; } } } dfs(0); cout << ans; return 0; } |
'PS) BOJ > DFS' 카테고리의 다른 글
[C++] 사다리조작 [백준 15684] (0) | 2018.08.15 |
---|