Game Develop

[Algorithm]Baekjoon 18428번 :: 감시 피하기 본문

Algorithm/Baekjoon

[Algorithm]Baekjoon 18428번 :: 감시 피하기

MaxLevel 2023. 5. 10. 17:17

https://www.acmicpc.net/problem/18428

 

18428번: 감시 피하기

NxN 크기의 복도가 있다. 복도는 1x1 크기의 칸으로 나누어지며, 특정한 위치에는 선생님, 학생, 혹은 장애물이 위치할 수 있다. 현재 몇 명의 학생들은 수업시간에 몰래 복도로 빠져나왔는데, 복

www.acmicpc.net

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
struct Node
{
    int y;
    int x;
};
 
int dir[4][2= { {-1,0}, {1,0}, {0,-1}, {0,1} };
char arr[7][7];
vector<int> v;
int n;
vector<Node> teachersInfo;
bool isBreak = false;
 
 
bool Check() // 모든 선생에 대해서 한번이라도 학생발견하면 return false;하고 전부종료
{
    for (int i = 0; i < teachersInfo.size(); ++i)
    {
        for (int j = 0; j < 4++j)
        {
            int curDirY = dir[j][0];
            int curDirX = dir[j][1];
 
            int curY = teachersInfo[i].y;
            int curX = teachersInfo[i].x;
 
            while (1)
            {
                curY += curDirY;
                curX += curDirX;
 
                if (curY < 0 || curY >= n) break;
                if (curX < 0 || curX >= n) break;
                if (arr[curY][curX] == 'O'break;
                if (arr[curY][curX] == 'T'break;
                if (arr[curY][curX] == 'S'return false;
            }
        }
    }
 
    return true;
}
 
 
void DFS(int index) // 수 뽑기
{
    if (isBreak) return;
 
    if (v.size() == 3// 수 다 뽑음.
    {
        if (Check())
        {
            isBreak = true;
        }
 
        return;
    }
 
    for (int i = index + 1; i < n * n; ++i)
    {
        if (arr[i / n][i % n] != 'X'continue;
 
        arr[i / n][i % n] = 'O';
        v.push_back(i);
 
        DFS(i);
 
        arr[i / n][i % n] = 'X';
        v.pop_back();
    }
}
 
 
int main(void)
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
 
    cin >> n;
 
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cin >> arr[i][j];
 
            if (arr[i][j] == 'T')
            {
                teachersInfo.push_back({ i,j });
            }
        }
    }
 
    for (int i = 0; i < n * n; ++i)
    {
        if (arr[i / n][i % n] != 'X'continue;
 
        arr[i / n][i % n] = 'O';
        v.push_back(i);
        
        DFS(i);
 
        arr[i / n][i % n] = 'X';
        v.pop_back();
    }
 
    if (isBreak) cout << "YES";
    else cout << "NO";
 
    return 0;
}
cs

백트래킹을 이용해 장애물을 설치할 경우의 수를 모두 구한 다음, 각각의 경우의 수마다 선생님을 기준으로 탐색을 해서 학생을 한번이라도 발견한다면 바로 false를 리턴한다.

n값이 굉장히 작기때문에 어떤방법이든 탐색만 제대로 하면 ANS를 받을 수 있다.