ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SWEA] 1953 탈주범 검거
    문제 풀이 2020. 5. 8. 18:51

    1953 탈주범 검거


    풀이)

    bfs를 이용해 탈주범이 이동하게 푼 문제이다


    핵심은

    각 터널마다 어떤 방향(상하좌우)로 움직일 수 있는지,

    방향으로 움직였을때 움직인 방향의 터널과 연결될 수 있는지를 저장해놓는 것이다.


    나같은 경우는 

    터널 구조물 1~7번 각각 어떤 방향으로 움직이는지를 vector <int> turner[8];에 저장하고

    방향으로 움직였을때 터널에 이어질 수 있는 지를 vector <int> connect[4];에 저장했다.


    turner[i] = i번째 터널일 경우 어떤 방향으로 움직일 수 있는지


    상하좌우를 0, 1, 2, 3 이라고 할때

    터널 구조물 1은 (십자가 모양) : 0, 1, 2, 3 방향 모두 움직일 수 있다.

    터널 구조물 2는 (세로막대기 모양) : 0, 1 방향으로만 움직일 수 있다.

    ...

    이런식으로 생각해 vector에 저장해놓았다.

    결과물

    vector <int> turner[8] = { {},{0,1,2,3},{0,1},{2,3},{0,3},{1,3},{1,2},{0,2} }; //터널은 1번부터 시작하니깐 0번은 빈공간으로 둠


    그리고 현재 터널에서 다음 칸의 터널로 움직일때,

    터널이 연결되어야 이동 가능하므로


    connect[i] = i방향으로 움직여서 갈때, 다음 칸의 터널이 뭐여야 하는지 


    예를 들어 

    현재 터널이 2번(세로막대기 모양)이면 움직일 수 있는 방향은 상 하 이다.

    그럼 으로 갔을 때 연결될 수 있는 터널은


     이런식으로 1번터널, 5번터널, 6번터널이다.


    이런식으로 생각해          상[0]      하[1]       좌[2]         우[3]        로 갈때 어떤 터널과 연결될 수 있는지 저장했다.

    결과물

    vector <int> connect[4] = { {1,2,5,6},{1,2,4,7},{1,3,4,5},{1,3,6,7} }; 



    따라서,

    이들을 이용해

    1. 현재 좌표 어떤 터널인지

    2. 그 터널에서는 어떤 방향(상하좌우)으로 갈 수 있는지

    3. 각 방향으로 갈 수 있는 지(다음 칸 터널 확인)


    를 반복해, 갈 수 있는 지점을 세어주면 결과가 나온다.


    코드)


    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
    #include <stdio.h>
    #include <queue>
    #include <string.h>
    #include <vector>
    using namespace std;
     
    int n,m,r,c,l;
    int map[50][50];
    bool visited[50][50];
    //상하좌우 0123
    int dy[4= { -1,1,0,0 };
    int dx[4= { 0,0,-1,1 };
     
    vector <int> turner[8= { {},{0,1,2,3},{0,1},{2,3},{0,3},{1,3},{1,2},{0,2} };
    vector <int> connect[4= { {1,2,5,6},{1,2,4,7},{1,3,4,5},{1,3,6,7} };
    int bfs(int time) {
        int cnt = 1;//갈수 있는 위치개수
        visited[r][c] = true;
        queue <pair<intint>> qu;
        qu.push({ r,c });
        while (!qu.empty())
        {
            int size = qu.size();
            while (size--)
            {
                int y = qu.front().first;
                int x = qu.front().second;
                int t = map[y][x];//현재 터널
                qu.pop();
                for (int i = 0; i < turnel[t].size(); i++) {
                    int dir = turner[t][i];
                    int ny = y + dy[dir];
                    int nx = x + dx[dir];
                    if (ny >= 0 && ny < n && nx >= 0 && nx < m) {
                        //이미 방문 터널 or 터널이 없는곳
                        if (visited[ny][nx] || map[ny][nx] == 0continue;
                        //이동해온 방향과 다음 터널과 연결될수있는지
                        bool fail = true;
                        for (int j = 0; j < 4; j++) {
                            if (connect[dir][j] == map[ny][nx]) {
                                fail = false;
                                break;
                            }
                        }
                        if (fail) continue;
                        visited[ny][nx] = true;
                        cnt++;
                        qu.push({ ny,nx });
                    }
                }
            }
            time--;
            if (time == 1break;
        }
        memset(visited, falsesizeof(visited));
        return cnt;
    }
     
    int main() {
        freopen("sample_input (1).txt""r", stdin);
        int T = 0;
        scanf("%d"&T);
        for (int test_case = 1; test_case <= T; test_case++) {
            scanf("%d %d %d %d %d"&n, &m, &r, &c, &l);
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    scanf("%d"&map[i][j]);
                }
            }
            if (l == 1) {
                printf("#%d 1\n", test_case);
            }
            else {
                printf("#%d %d\n", test_case, bfs(l));
            }
            
        }
     
        return 0;
    }
    cs


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

    [SWEA] 5653. 줄기세포배양  (0) 2020.05.09
    [SWEA] 1952. 수영장  (0) 2020.05.08
    [SWEA] 2382 미생물 격리  (0) 2020.05.07
    [SWEA] 2477 차량 정비소  (0) 2020.05.06
    [SWEA] 2112. 보호필름  (0) 2020.05.04

    댓글

Designed by Tistory.