1. 약품 칠하는 칸이 k개가 넘지 않도록 백트래킹 한다.
2. 모든 경우에 대해 타당한지 확인 후 최소값 출력한다.
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 | #include <iostream> #include <algorithm> using namespace std; int t, d, w, k, res; int map[14][21]; bool check[14]; void printAll() { cout << endl; for (int i = 1; i <= d; i++) { if (check[i]) cout << "o "; else cout << "x "; } cout << endl; } bool isOK(int n) { int a, b; bool flag; if (n == 0) { for (int i = 1; i <= w; i++) { a = 0; b = 0; flag = false; for (int j = 1; j <= d; j++) { if (map[j][i] == 0 || check[j]) { a++; b = 0; } else if (map[j][i] == 1) { b++; a = 0; } if (a == k || b == k) { flag = true; break; } } if (!flag) return false; } } else { for (int i = 1; i <= w; i++) { a = 0; b = 0; flag = false; for (int j = 1; j <= d; j++) { if (map[j][i] == 1 || check[j]) { b++; a = 0; } else if (map[j][i] == 0 || check[j]) { a++; b = 0; } if (a == k || b == k) { flag = true; break; } } if (!flag) return false; } } return true; } void dfs(int idx, int cnt) { if (cnt == k + 1 || cnt >= res) return; check[idx] = true; if (isOK(0) || isOK(1)) { res = min(res, cnt); //printAll(); } for (int i = idx + 1; i <= d; i++) { dfs(i, cnt + 1); } check[idx] = false; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> t; for (int tc = 1; tc <= t; tc++) { cin >> d >> w >> k; for (int i = 1; i <= d; i++) { for (int j = 1; j <= w; j++) { cin >> map[i][j]; } } res = 987654321; dfs(0, 0); cout << "#" << tc << " " << res << endl; } } | cs |
'SWEA::문제풀이' 카테고리의 다른 글
4676 늘어지는 소리 만들기 (0) | 2018.07.14 |
---|---|
2117 홈 방범 서비스 (0) | 2018.04.14 |
4112 이상한 피라미드 탐험 (0) | 2018.04.12 |
2383 점심 식사시간 (4) | 2018.04.11 |
1861 정사각형 방 (0) | 2018.04.10 |