일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- NRVO
- Unreal Engine5
- 프로그래머스
- 1563
- C++
- 언리얼엔진5
- GeeksForGeeks
- RootMotion
- Frustum
- IFileDialog
- 2294
- C
- winapi
- 팰린드롬 만들기
- UE5
- UnrealEngine5
- const
- Programmers
- directx
- 오블완
- algorithm
- baekjoon
- 백준
- DeferredRendering
- UnrealEngine4
- 줄 세우기
- 티스토리챌린지
- DirectX11
- RVO
- softeer
- Today
- Total
Game Develop
[Algorithm] Baekjoon 3197번 : 백조의 호수 본문
https://www.acmicpc.net/problem/3197
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
|
struct Node
{
int y;
int x;
};
int dir[4][2] = { {-1,0}, {1,0}, {0,-1}, {0,1} };
int r, c;
int arr[1501][1501] = { 0 };
bool visited[1501][1501] = { false };
int meltDay = 0;
int swanDay = 0;
vector<Node> swans;
vector<Node> prevAddedNodes;
bool CheckMeeting()
{
prevAddedNodes.push_back({ swans[0].y,swans[0].x });
while (!prevAddedNodes.empty())
{
++swanDay;
queue<Node> q;
for (int i = 0; i < prevAddedNodes.size(); ++i)
{
q.push(prevAddedNodes[i]);
visited[prevAddedNodes[i].y][prevAddedNodes[i].x] = true;
}
prevAddedNodes.clear();
while (!q.empty())
{
int curY = q.front().y;
int curX = q.front().x;
q.pop();
if (curY == swans[1].y && curX == swans[1].x)
{
return true;
}
for (int i = 0; i < 4; ++i)
{
int nextY = curY + dir[i][0];
int nextX = curX + dir[i][1];
if (nextY < 0 || nextY >= r) continue;
if (nextX < 0 || nextX >= c) continue;
if (visited[nextY][nextX]) continue;
if (arr[nextY][nextX] <= swanDay + 2)
{
q.push({ nextY,nextX });
visited[nextY][nextX] = true;
}
else if (arr[nextY][nextX] == swanDay + 3) // 현재날짜의 얼음을 만난다면
{
prevAddedNodes.push_back({ nextY,nextX });
visited[nextY][nextX] = true;
}
}
}
}
return false;
}
void Melt()
{
while (!prevAddedNodes.empty())
{
++meltDay;
queue<Node> q;
for (int i = 0; i < prevAddedNodes.size(); ++i)
{
q.push(prevAddedNodes[i]);
}
prevAddedNodes.clear();
while (!q.empty())
{
int curY = q.front().y;
int curX = q.front().x;
q.pop();
for (int i = 0; i < 4; ++i)
{
int nextY = curY + dir[i][0];
int nextX = curX + dir[i][1];
if (nextY < 0 || nextY >= r) continue;
if (nextX < 0 || nextX >= c) continue;
if (arr[nextY][nextX] == meltDay + 2) continue; // 같은날 녹은거면
if (arr[nextY][nextX] == 0 || arr[nextY][nextX] == 2)
{
q.push({ nextY,nextX }); // 얼음찾을때까지 탐색.
arr[nextY][nextX] = meltDay + 2;
}
else if (arr[nextY][nextX] == 1) // 얼음이면
{
arr[nextY][nextX] = meltDay + 2; // 물로 녹이기 (접근 불가능한)
prevAddedNodes.push_back({ nextY,nextX });
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> r >> c;
for (int i = 0; i < r; ++i)
{
for (int j = 0; j < c; ++j)
{
char temp;
cin >> temp;
if (temp == '.')
{
arr[i][j] = 0;
prevAddedNodes.push_back({ i,j });
}
else if (temp == 'X')
{
arr[i][j] = 1;
}
else
{
arr[i][j] = 2;
swans.push_back({ i,j });
prevAddedNodes.push_back({ i,j });
}
}
}
Melt();
CheckMeeting();
cout << swanDay;
}
|
cs |
시간줄이는걸 잘해야 하는 문제.
즉, 필요한만큼의 노드만 생성을 해야 한다.
각 날마다 녹은 얼음에 대해서 별도의 버퍼큐에 보관한다. 나같은 경우 걍 prevAddedNodes라는 벡터에다가 보관했다.
그리고 다음날 얼음을 녹이기 위한 탐색을 할 떄 딱 그 버퍼큐에 있는 노드들에 한해서만 탐색을 진행한다.
기존에 탐색했던 물부분이라던가 얼음부분에 대해서는 새롭게 탐색할 필요가 없다. 이부분을 명심하자.
이전 부분들도 탐색하려 할 경우 시간초과에 걸리거나 큐에 노드가 너무 들어가서 메모리초과가 발생하게 된다.
얼음을 녹일 때, 현재날짜에 기반해서 arr에다가 녹인날짜를 기록한다. 나같은 경우 현재날짜 +2를 기록했다.
이런식으로 Melt를 끝내면 arr에 각 얼음이 녹은날짜가 3부터시작해서 예쁘게 표시되어있다.
이걸 기반으로 백조의 길찾기를 수행한다. 마찬가지로 1일부터 시작하게 되는데, arr[nextY][nextX]의 값이 현재날짜 +2 '이하'라면, 얼음을 찾을 때까지 (얼음은 현재날짜 + 3) 탐색을 진행한다. 이 탐색을 진행하다 다른 백조를 만나면 끝이다.
만약 얼음을 만나면 얼음을 녹일때와 마찬가지로 해당 좌표노드들을 버퍼큐에 넣는다. (당연 현재 큐에는 넣으면 안된다)
이런식으로 필요한만큼의 노드만 큐에 넣는게 중요하다.
사실 나같은경우 예전부터 은연중에 필요한 노드들만 사용하기위해 prevAddedNodes를 사용하긴 했었는데, 내가 이걸 녹이는데에만 쓰고 백조탐색에는 적용 안해서 시간초과가 나왔었다.
'Algorithm > Baekjoon' 카테고리의 다른 글
[Algorithm] Baekjoon 2933번 : 미네랄 (0) | 2023.05.06 |
---|---|
[Algorithm] Baekjoon 1799번 : 비숍 (0) | 2023.05.03 |
[Algorithm] Baekjoon 18809번 : Gaaaaaaaaaarden (0) | 2023.05.02 |
[Algorithm] Baekjoon 6603번 : 로또 (0) | 2023.05.02 |
[Algorithm] Baekjoon 15665번 : N과 M (11) (0) | 2023.05.01 |