ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SWEA] 1824 혁진이의 프로그램 검증
    문제 풀이 2020. 4. 21. 22:48

    1824 혁진이의 프로그램 검증


    풀이)

    dfs를 통해 탐색해준 문제이다.


    주의할점은 ? 문자와 cycle 여부이다.


    1. 문자일 경우, 4방향으로 바뀔 확률이 동일하니깐 4방향 모두 탐색해봄으로 해결했다.


    2. sample_input의 2번 처럼, 

       (sample 2)

        2 6

        5>--v.
        .^--_@

       탐색이 끝나지 않고 계속 돌아가는 상황이 생길 수 있다. -> cycle 생성


       이는 bool visited[20][20][16][4] 4차원 배열을 통해 한 번 겪었던 상황이면 다시 겪지 않도록 해줬다.


       visited[r][c][mem][direction] == true?

       : r행 c열 번째 칸을 메모리에 mem 정수가 저장되어있고, 방향이 dir일때 방문했었다 라는 뜻.



    코드)


    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
    #include <stdio.h>
    #include <iostream>
    #include <cstring> //memset()함수를 쓰기위해
    using namespace std;
     
    int T, r, c, memory, dir;
    bool result;
    int dx[4= { 001-1 };
    int dy[4= { 1-100 }; //우좌하상
    char map[20][20];
    bool visited[20][20][16][4];
     
    void dfs(int x, int y) {
        if (result) return//프로그램 실행 정지될 수 있다면
     
        if (visited[x][y][memory][dir]) return//이미 겪었던 상황이라면
        else visited[x][y][memory][dir] = true;
     
     
        switch (map[x][y]) {
        
        case '>':
            dir = 0;
            break;
        case '<':
            dir = 1;
            break;
        case 'v':
            dir = 2;
            break;
        case '^':
            dir = 3;
            break;
        case '_':
            if (memory == 0) dir = 0;
            else dir = 1;
            break;
        case '|':
            if (memory == 0) dir = 2;
            else dir = 3;
            break;
        case '@':
            result = true;
            return;
        case '+':
            if (memory == 15) memory = 0;
            else memory += 1;
            break;
        case '-':
            if (memory == 0) memory = 15;
            else memory -= 1;
            break;
        }
     
        if ('0' <= map[x][y] && map[x][y] <= '9') {
            memory = map[x][y] - '0';
        }
     
        if (map[x][y] == '?') {
            for (int i = 0; i < 4; i++) {
                int nr = x + dx[i];
                int nc = y + dy[i];
     
                if (0 > nr || nr >= r || 0 > nc || nc >= c) {
                    if (i == 0) nc = 0;
                    else if (i == 1) nc = c - 1;
                    else if (i == 2) nr = 0;
                    else nr = r - 1;
                }
     
                int tmp = dir;
                dir = i;
                dfs(nr, nc);
                dir = tmp;
            }
        }
        else {
            int nr = x + dx[dir];
            int nc = y + dy[dir];
     
            if (0 > nr || nr >= r || 0 > nc || nc >= c) { //우좌하상
                if (dir == 0) nc = 0;
                else if (dir == 1) nc = c - 1;
                else if (dir == 2) nr = 0;
                else nr = r - 1;
            }
     
            dfs(nr, nc);
        }
     
    }
     
    int main() {
        scanf("%d"&T);
        for (int test_case = 1; test_case <= T; test_case++) {
            scanf("%d %d"&r, &c);
     
            for (int i = 0; i < r; i++) {
                for (int j = 0; j < c; j++) {
                    scanf(" %c"&map[i][j]);
                }
            }
     
            memory = 0;
            dir = 0;
            result = false;
            memset(visited, falsesizeof(visited));
            dfs(00);
     
            if (result) printf("#%d YES\n", test_case);
            else printf("#%d NO\n", test_case);
        }
    }
    cs


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

    [SWEA] 2806 N-Queen  (0) 2020.04.23
    [SWEA] 1954 달팽이 숫자  (0) 2020.04.22
    [SWEA] 2819번 격자판의 숫자 이어 붙이기  (0) 2020.04.20
    [SWEA] 3752번 가능한 시험 점수  (0) 2020.04.18
    [SWEA] 1249번 보급로  (0) 2020.04.18

    댓글

Designed by Tistory.