ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SWEA] 2112. 보호필름
    문제 풀이 2020. 5. 4. 18:27

    2212 보호필름


    풀이)

    재귀 + 브루트 포스 문제였다.


    필름 막 상태를 vector<vector<int>> arr;에 저장해 놓았다.

    그리고 약품으로 막 상태를 바꾼다면 기존의 값을 알아놔야하기 때문에


    처음에는

    vector<vector<int>> temp =arr; 로 전체 상태를 저장해놓은 뒤,

    막 상태 바꾼 후 arr= temp; 로 돌려놓았는데 이렇게 하니 시간초과가 났다.


    아무래도 백터 전체를 저장하고 돌려놓고 해서 그런듯 싶어


    두번째로는 필름 막 상태 모두를 저장해놓지 않고,

    기존의 막 상태(행)만 저장해두고 vector<int> temp = arr[i]; (i는 바꿀 막 인덱스)

    상태 바꾼 후 원래 막 상태로 바꿔주도록 했더니 arr[i] = temp;

    시간 초과가 나지 않고 통과했다. 


    시간초과가 나지 않게 사용한 방법은 위에서 설명한 거 말고 2가지가 더있다.

    1. k=1일때는 바로 0 출력

    2. 성능 검사할 때, 열들을 계산하는데 이 때 해당 열에서 통과가 되면 바로 다음 열로 넘어간다.



    막 상태 변경할때는 

    예를 들어 두께가 5인 보호필름이 있고 k = 3이라면,

    (편의상 인덱스를 1,2,3,4,5라고 하겠다)


    1. 상태 한번 바꿈

    1

    2

    3

    4

    5


    2. 상태 두번 바꿈

    1 -> 2

      -> 3

      -> 4

      -> 5

    2 -> 3

      -> 4

      -> 5

    .

    .

    .

    3. 상태 세번 바꿈


    1 ->2 -> 3

    2 -> 4

    2 -> 5

    3 -> 4

    3 -> 5

    4 -> 5


    2 ->3 -> 4

          3 -> 5

          4 -> 5

    .

    .

    .

    이런 식으로 상태를 몇 번 바꿀지, 

    바꾼다면 어떤 막(= 행, column)을 바꿀지 while문을 통해 계속 확인해줬다.


    행들을 바꿀 때마다 A상태, B상태 한 번씩다 바꿔서 확인해줬다.


    코드)


    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
    #include <stdio.h>
    #include <vector>
    #include <algorithm>
    using namespace std;
     
    int d, w, k;
    vector <vector<int>> arr;
    bool result;
     
    //성능검사하는 함수
    void check() {
        bool fail = false;
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < d; j++) {
                if (d - j < k) {
                    fail = true;
                    break;
                }
                int cnt = 1;
                for (int t = 1; t < k; t++) {
                    if (arr[j][i] == arr[j + t][i]) {
                        cnt++;
                    }
                    else break;
                }
                if (cnt == k) break;
                
            }
            if (fail) break;
        }
     
        if (fail) return;
        else {
            result = true;
            return;
        }
    }
     
    void dfs(int row,int depth,int limit) {
        if (result) return;
        if (depth >= limit) {
            check();        
            return;
        }
        for (int i = row; i < d; i++) {
            vector<int> temp = arr[i];
            fill(arr[i].begin(), arr[i].end(), 0); //i번째 막을 A상태로
            dfs(i+1, depth + 1, limit);
            fill(arr[i].begin(), arr[i].end(), 1); //i번째 막을 B상태로
            dfs(i+1, depth + 1, limit);
            arr[i] = temp;
            if (result) return;
        }
    }
     
    int main() {
        freopen("sample_input.txt""r", stdin);
        int T = 0;
        scanf("%d"&T);
        arr.resize(13);
        for (int i = 0; i < 13; i++) {
            arr[i].resize(20);
        }
        for (int test_case = 1; test_case <= T; test_case++) {
            //arr.clear();
            scanf("%d %d %d"&d, &w, &k);
            
            for (int i = 0; i < d; i++) {
                for (int j = 0; j < w; j++) {
                    scanf("%d"&arr[i][j]);
                }
            }
     
            if (k == 1) {
                printf("#%d 0\n", test_case);
                result = false;
                continue;
            }
            //약품투입안할때
            check();
            if (result) {
                printf("#%d 0\n", test_case);
                result = false;
                continue;
            }
            //투입할때
            int cnt = 1//바꿀 막 개수
            while (true)
            {
                dfs(00, cnt);
                if (result) break;
            
                cnt++;
            }
            printf("#%d %d\n", test_case, cnt);
            result = false;
        }
        return 0;
    }
    cs


    '문제 풀이' 카테고리의 다른 글

    [SWEA] 2382 미생물 격리  (0) 2020.05.07
    [SWEA] 2477 차량 정비소  (0) 2020.05.06
    [SWEA]2105 디저트 까페  (0) 2020.05.01
    [SWEA] 1949 등산로 조성  (0) 2020.04.29
    [SWEA] 2817 부분수열의 합  (0) 2020.04.28

    댓글

Designed by Tistory.