기술 블로그

1953번 탈주범 검거 본문

알고리즘 문제/SW Expert Academy

1953번 탈주범 검거

parkit 2018. 8. 25. 21:00
728x90
반응형

문제 : https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PpLlKAQ4DFAUq


해설 : https://www.swexpertacademy.com/main/learn/course/subjectDetail.do?subjectId=AV7HLJ66CZIDFAXB




처음에 DFS로 풀다가, 실행을 하면서 테스트 케이스과 그림을 확인해보니, DFS로 풀면 안 된다는 것을 깨달았다.


그래서, BFS로 풀었다. 난이도는 쉬웠다.



BFS를 진행하면서 2가지만 확인해주면 됐다.


1. map[행][열]이 0인 곳은 가지 않는다.

2. 상황에 따라 현재 있는 터널 구조물에서 다음 위치(상, 하, 좌, 우)에 있는 터널 구조물로 갈 수 있는지 여부.(go() 함수)



그런데, '제출' 버튼을 클릭하니, 50개의 테스트 케이스 중 49개만 맞다고 떠버렸다.


그래서 무엇이 오류일까 생각하다가


134번 째 줄에 있는 코드(if (thread >= L - 1) return;)를 114번 째로 옮기니, 그제서야 맞다고 떴다.


그래서 뭐가 다른걸까 위치를 잘 생각해봐서, 예외를 생각해보니


1

5 6 2 1 1

0 0 5 3 6 0

0 0 2 0 2 0

3 3 1 3 7 0

0 0 0 0 0 0

0 0 0 0 0 0


위의 예외가 있었다.


134번 째 줄에 있는 코드로 실행했을 때는 3이 나오지만, 

정답이 뜬 114번 째 줄에 있는 코드로 실행했을 때는 1이 나온다.


왜냐하면, 134번 째 줄에 있을 때는 L이 1일 때, 

이미 위에서 while(qSize--)문이 실행된 후(visit가 방문 처리가 됨. )에 실행이 되기 때문이다.


즉, L이 1일 때에는 그 자리에서 바로 끝내야 하는데, 134번 째 줄에 있을 때는 옆으로 이동할 수 있는 터널 구조물이 있기 때문에

방문처리가 되버리기 때문이다.


다음부터는 이런 실수를 줄이도록 해야겠다.





<정답 코드>

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <math.h>
#include <algorithm>
 
using namespace std;
 
int map[51][51= { 0, };
 
bool visit[51][51= { false, };
 
int R = 0, C = 0, L = 0;
int N = 0, M = 0, T = 0;
 
 
int dy[4= { -1010 };
int dx[4= { 0-10 , 1 };
int dir[4= { 0123 };
//               ↑ ← ↓ →
 
bool go(int before, int after, int d)
{
    if (d == 0// 위로 이동할 때
    {
        if (before == 3 || before == 5 || before == 6)
        {
            return false;
        }
        else
        {
            if (after == 1 || after == 2 || after == 5 || after == 6)
            {
                return true;
            }
        }
 
        return false;
    }
    else if (d == 1// 왼쪽으로 이동할 때
    {
        if (before == 2 || before == 4 || before == 5)
        {
            return false;
        }
        else
        {
            if (after == 1 || after == 3 || after == 4 || after == 5)
            {
                return true;
            }
        }
 
        return false;
    }
    else if (d == 2// 아래로 이동할 때
    {
        if (before == 3 || before == 4 || before == 7)
        {
            return false;
        }
        else
        {
            if (after == 1 || after == 2 || after == 4 || after == 7)
            {
                return true;
            }
        }
 
        return false;
    }
    else if (d == 3// 오른쪽으로 이동할 때
    {
        if (before == 2 || before == 6 || before == 7)
        {
            return false;
        }
        else
        {
            if (after == 1 || after == 3 || after == 6 || after == 7)
            {
                return true;
            }
        }
 
        return false;
    }
}
 
void BFS(int r, int c)
{
    queue<pair<intint> > q;
 
    q.push({ r, c });
 
    visit[r][c] = true;
 
    int thread = 0;
 
    while (!q.empty())
    {
        int qSize = q.size();
 
        while (qSize--)
        {
            int y = q.front().first;
            int x = q.front().second;
 
            q.pop();
 
            if (thread >= L - 1return;
 
            for (int i = 0; i < 4; i++)
            {
                int ny = y + dy[i];
                int nx = x + dx[i];
                int direction = dir[i];
 
                if (0 <= ny && ny < N && 0 <= nx && nx < M && !visit[ny][nx] && map[ny][nx] != 0 && go(map[y][x], map[ny][nx], direction))
                {
                    visit[ny][nx] = true;
                    
                    q.push({ ny, nx });
                }
            }
        }        
 
        ++thread;
        
        // 내가 틀린 이유
        // if (thread >= L - 1) return;
    }
}
 
int getCount()
{
    int ret = 0;
 
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (visit[i][j])
            {
                ++ret;
            }
        }
    }
 
    return ret;
}
 
int main(void)
{
    scanf("%d"&T);
 
    for (int tc = 1; tc <= T; tc++)
    {
        memset(visit, falsesizeof(visit));
 
        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]);
            }
        }
 
        BFS(R, C);
        
        printf("#%d %d\n", tc, getCount());
    }
 
    return 0;
}
cs





728x90
반응형

'알고리즘 문제 > SW Expert Academy' 카테고리의 다른 글

2382번 미생물 격리  (0) 2018.08.29
1952번 수영장  (0) 2018.08.27
2383번 점심 식사시간  (0) 2018.08.25
1267번 작업순서  (0) 2018.08.25
4013번 특이한 자석  (0) 2018.08.24