모든 경우의 수를 검사해야 한다. 


여러가지 방법이 있겠지만 비트마스크와 bfs를 사용해서 풀었다.


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
#include <iostream>
#include <memory.h>
using namespace std;
#define mod 600000
 
struct p {
    // x = 비트마스크. 표시된 곳을 이미 처리했다는 의미
    int x, cnt, idx;
};
 
int arrs[mod][20], D, W, K;
// queue
p q[mod];
 
bool check(int arr[20]) {
    // tt = K개의 연속한 비트. 
    int tt = (1 << K) - 1, f;
    for (int i = 0; i < W; ++i) {
        f = 0;
        for (int j = 0; j <= D - K; ++j) {
            int temp = arr[i] & (tt << j);
            // &해서 tt가 그대로 나오면 1이 K개 연속, 모두 0이면 0이 3개연속
            if (temp == (tt << j) || temp == 0) {
                f = 1;
                break;
            }
        }
        if (!f) return false
    }
    return true;
}
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int t, a[20], i, j;
    int aidx, qs, qe;
    cin >> t;
    for (int tc = 1; tc <= t; ++tc) {
        memset(a, 0sizeof(a));
        cin >> D >> W >> K;
        // 입력받으면서 비트마스크를 만든다
        for (i = 0; i < D; ++i) for (int j = 0; j < W; ++j) {
            int temp;
            cin >> temp;
            a[j] = (a[j] << 1| temp;
        }
        for (i = 0; i < W; ++i) arrs[0][i] = a[i];
        qs = qe = aidx = 1;
        
        cout << "#" << tc << " ";
        
        if (check(arrs[0])) {
            cout << "0\n";
        }
        else {
            int maxp = 1 << D, f = 1, ans = K;
 
            // i 원소부터 시작하는 항 만들기
            for (i = 1; i < maxp; i <<= 1) {
                int nx = i;
                for (j = 0; j < W; ++j) arrs[aidx][j] = a[j] & ~i;
                if (check(arrs[aidx])) {
                    ans = 1;
                    break;
                }
                if (!(nx & 1)) {
                    q[qe++= { nx,1,aidx };
                    aidx++;
                }
 
                for (j = 0; j < W; ++j) arrs[aidx][j] = a[j] | i;
                if (check(arrs[aidx])) {
                    ans = 1;
                    break;
                }
                if (!(nx & 1)) {
                    q[qe++= { nx,1,aidx };
                    aidx++;
                }
            }
 
            while (qs<qe && f) {
                int x = q[qs].x;
                int cnt = q[qs].cnt;
                int idx = q[qs++].idx;
                
                if (cnt != K - 1) {
                    // i = x의 최하위 비트. 그 아래만 순회한다
                    for (i = (x&-x) >> 1; i; i >>= 1) {
                        int nx = x | i;
                        // &~i = i 비트를 0으로 만들어 본다
                        for (j = 0; j < W; ++j) arrs[aidx][j] = arrs[idx][j] & ~i;
                        if (check(arrs[aidx])) {
                            ans = cnt + 1;
                            f = 0;
                            break;
                        }
                        if (!(nx & 1)) {
                            q[qe++= { nx,cnt + 1,aidx };
                            aidx++;
                        }
                        // | i = i 비트를 1로 만들어 본다
                        for (j = 0; j < W; ++j) arrs[aidx][j] = arrs[idx][j] | i;
                        if (check(arrs[aidx])) {
                            ans = cnt + 1;
                            f = 0;
                            break;
                        }
                        if (!(nx & 1)) {
                            q[qe++= { nx,cnt + 1,aidx };
                            aidx++;
                        }
                    }
                }
                else break;
            }
            cout << ans << '\n';
        }
    }
    return 0;
}
cs


'SWEA' 카테고리의 다른 글

5789. 현주의 상자 바꾸기  (0) 2018.10.16
1824. 혁진이의 프로그램 검증  (0) 2018.10.08
4740. 밍이의 블록게임  (0) 2018.10.07
핀볼 런타임 에러나는 TC  (0) 2018.10.07
5644. 무선 충전  (0) 2018.09.27

+ Recent posts