Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- UnrealEngine4
- GeeksForGeeks
- 줄 세우기
- baekjoon
- winapi
- 1563
- RootMotion
- 티스토리챌린지
- NRVO
- algorithm
- Unreal Engine5
- 오블완
- 팰린드롬 만들기
- 백준
- DeferredRendering
- const
- DirectX11
- UnrealEngine5
- C++
- 2294
- RVO
- IFileDialog
- Programmers
- C
- 언리얼엔진5
- directx
- softeer
- Frustum
- 프로그래머스
- UE5
Archives
- Today
- Total
Game Develop
[Algorithm] Baekjoon 16933번 : 벽 부수고 이동하기3 본문
https://www.acmicpc.net/problem/16933
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
|
struct Node
{
int y;
int x;
int breakCount;
bool isNight;
};
int dir[4][2] = { {-1,0}, {1,0}, {0,-1}, {0,1} };
int row, col, breakCount;
int arr[1001][1001];
int visited[1001][1001][11][2];
int BFS()
{
memset(visited, 0x3f, sizeof(visited));
queue<Node> q;
q.push({ 0,0,breakCount,false });
for (int i = 0; i <= breakCount; ++i)
{
visited[0][0][i][0] = 1; // 낮
visited[0][0][i][1] = 1; // 밤
}
while (!q.empty())
{
int curY = q.front().y;
int curX = q.front().x;
int curBreakCount = q.front().breakCount;
bool curIsNight = q.front().isNight;
q.pop();
if (curY == row - 1 && curX == col - 1)
{
int result = visited[curY][curX][curBreakCount][curIsNight];
return result;
}
if (curIsNight) // 지금이 밤이라면, 제자리에 있을지 고려할만하다. 제자리에서 낮이됐을 때 이득볼 경우의 수가 존재하니까 (벽을 부술수있음)
{
if (visited[curY][curX][curBreakCount][1] + 1 < visited[curY][curX][curBreakCount][0]) // 낮이 됐을 때 더 적은횟수면.
{
visited[curY][curX][curBreakCount][0] = visited[curY][curX][curBreakCount][1] + 1;
q.push({ curY,curX,curBreakCount,false });
}
}
for (int i = 0; i < 4; ++i)
{
int nextY = curY + dir[i][0];
int nextX = curX + dir[i][1];
if (nextY < 0 || nextY >= row) continue;
if (nextX < 0 || nextX >= col) continue;
if (arr[nextY][nextX] == 0) // 다음이 빈공간이면 (낮이든 밤이든)
{
if (visited[nextY][nextX][curBreakCount][!curIsNight] > visited[curY][curX][curBreakCount][curIsNight] + 1) // 이전에 진입한놈은 더 많은 횟수로 진입했을 때,
{
visited[nextY][nextX][curBreakCount][!curIsNight] = visited[curY][curX][curBreakCount][curIsNight] + 1;
q.push({ nextY,nextX,curBreakCount,!curIsNight });
}
}
else // 다음이 벽이면
{
if (!curIsNight) // 그리고 낮이면 (낮에만 부술수있으니까)
{
if (curBreakCount >= 1 && visited[nextY][nextX][curBreakCount - 1][!curIsNight] > visited[curY][curX][curBreakCount][curIsNight] + 1)
{
visited[nextY][nextX][curBreakCount - 1][!curIsNight] = visited[curY][curX][curBreakCount][curIsNight] + 1;
q.push({ nextY,nextX,curBreakCount - 1,!curIsNight });
}
}
}
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> row >> col >> breakCount;
string temp;
for (int i = 0; i < row; ++i)
{
cin >> temp;
for (int j = 0; j < col; ++j)
{
arr[i][j] = temp[j] - '0';
}
}
int result = BFS();
cout << result;
}
|
cs |
이전문제인 벽 부수고 이동하기2에서 '낮과 밤'이라는 조건이 추가된 문제이다.
일단 낮과 밤이라는 경우의수까지 고려하기 위해 visited를 [1001][1001][11][2]로 설정한다.
그리고 보면 이동하지 않고 제자리에서 시간을 보낼수도 있다고 한다.
즉, 낮일 때 제자리에 있으면 이동했을 때처럼 1을 카운팅하고 밤으로 바뀐다. 밤이면 낮으로 바뀐다.
그러면 제자리에 있을 때 이득인 경우에만 제자리에서 있기를 수행해야할 텐데, 문제에서의 조건을 보면 '낮일때만 벽을 부수기가 가능하다..'라는 조건이 있다.
만약 당장 벽을부수면 매우 빠르게 도착지점을 갈 수 있는데 밤이라서 못부순다고 생각해보자.
그러면 1을 카운팅하더라도 낮까지 기다리는게 이득이 있는 상황이 분명히 있다.
그렇기 때문에 현재 노드가 밤인 경우에만, 조건을 고려해서 낮까지 기다리는 노드를 큐에 넣는다 (무조건 넣는것은 아니다)
현재가 낮이라면 밤까지 기다려서 이득볼 수 있는 경우의수가 전혀 없으므로 무시한다.
나머지는 이전문제랑 동일하다.
'Algorithm > Baekjoon' 카테고리의 다른 글
[Algorithm] Baekjoon 2785번 : 체인 (0) | 2023.03.04 |
---|---|
[Algorithm] Baekjoon 11501번 : 주식 (0) | 2023.03.02 |
[Algorithm] Baekjoon 14442번 : 벽 부수고 이동하기2 (0) | 2023.03.01 |
[Algorithm] Baekjoon 2146번 : 다리 만들기 (1) | 2023.03.01 |
[Algorithm] Baekjoon 9466번 : 텀 프로젝트 (1) | 2023.02.28 |