반응형
https://www.acmicpc.net/problem/3055
3055번: 탈출
사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제
www.acmicpc.net
1.문제설명
3 6
D...*.
.X.X..
....S.
물은 상하좌우로 퍼진다. 고슴도치는 상하좌우로 한 칸 씩 이동할 수 있다
X는 물, 고슴도치 모두 지날 수 없다
D는 고슴도치만 갈 수 있다.
고슴도치가 물을 피해 D로 갈 수 있다면 최소 시간을 출력하고,
그럴 수 없다면 문제에서 제시한 문자열을 출력해준다.
2.접근 방법[알고리즘]
1. 물을 상하좌우로 퍼트린다.
2. 고슴도치를 물이 없는 곳으로 상하좌우 이동시킨다.
3. 1,2를 반복하면서 고슴도치가 D를 방문하면 시간을 출력하고 종료한다.
4. D를 방문할 수 없으면 "KAKTUS" 를 출력한다.
이 문제에서 물과 고슴도치 모두 BFS를 동시에 해주어야 한다.
각각의 큐를 만들고 시간을 증가시키면서 새로 방문한 노드에 대해서 일괄적으로 상하좌우 탐색한다.
고슴도치는 물이 방문할 점을 방문할 수 없기 때문에
물 -> 고슴도치 -> 물 -> 고슴도치 순으로 BFS를 돈다.
3.문제풀이코드 C++
#include <bits/stdc++.h>
using namespace std;
int r, c;
char arr[53][53];
bool s_check[53][53], wt_check[53][53];
int ch[53][53];
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
//물 먼저 이동 후 고슴도치 이동
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> r >> c;
queue<pair<int, int> > wt;
queue<pair<int, int> > s;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cin >> arr[i][j];
if (arr[i][j] == '*') {
ch[i][j] = -1;
wt.push({ i,j });
wt_check[i][j] = 1;
}
else if (arr[i][j] == 'S') {
ch[i][j] = 1;
s.push({ i,j });
s_check[i][j] = 1;
}
else if (arr[i][j] == 'X') {
ch[i][j] = 2;
}
else if (arr[i][j] == 'D') {
ch[i][j] = 3;
}
}
}
int t = 0;
while (true) {
int s_size = s.size();
int wt_size = wt.size();
if (s_size == 0) break;
for (int i = 0; i < wt_size; i++) {
int x = wt.front().first;
int y = wt.front().second;
wt.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx <= 0 || nx > r || ny <= 0 || ny > c||wt_check[nx][ny] == 1) continue;
if (ch[nx][ny] == 0 || ch[nx][ny]==1) {
wt_check[nx][ny] = 1;
ch[nx][ny] = -1;
wt.push({ nx,ny });
}
}
}
for (int i = 0; i < s_size; i++) {
int x = s.front().first;
int y = s.front().second;
s.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx <= 0 || nx > r || ny <= 0 || ny > c || s_check[nx][ny] == 1) continue;
if (ch[nx][ny] == 0 || ch[nx][ny] == 1 ) {
ch[nx][ny] = 1;
s_check[nx][ny] = 1;
s.push({ nx,ny });
}
else if (ch[nx][ny] == 3) {
cout << t+1;
return 0;
}
}
}
t++;
//print();
}
cout << "KAKTUS" << '\n';
return 0;
}
틀린이유
처음에 고슴도치와 물이 방문한 좌표를 체크해주지 않아 틀렸다
BFS든 DFS든 방문해준 점을 체크표시해주지 않으면 방문한 곳을 계속 방문해서 무한 루프에 빠지고 만다.
그로 인해 시간초과나 메모리초과가 발생한다.
반응형
'Algorithm > problem' 카테고리의 다른 글
백준 14923 : 미로 탈출 문제풀이코드 C++ (0) | 2022.02.04 |
---|---|
백준 2206번: 벽 부수고 이동하기 문제풀이 및 반례 모음 (0) | 2022.02.03 |
백준 17090번 : 미로 탈출하기 C++ 문제 풀이 (0) | 2022.02.03 |
백준 17142번: 연구소 3 - DFS, BFS, 백트래킹 C++코드 (0) | 2022.02.03 |
백준 17141번 : 연구소 2 - BFS DFS 백트래킹 응용 문제 (0) | 2022.02.02 |