반응형
문제 : https://www.acmicpc.net/problem/2206
서론
크게 어렵게 생각 안했는데 시간초과를 연타로 맞았다.
DFS로 구현했다가 시간초과
같은 아이디어를 BFS로 구현했다가 시간초과
방문배열을 3차원으로 만들었는데 시간초과
큐에서 꺼낸 후 방문체크에서 꺼내기 전 방문체크로 수정해서 통과
많은걸 얻어가는 문제다.
풀이과정
기존의 이동할 곳이 0이면 방문하고 1이면 방문하지 않는것에서
조건을 하나 추가해준다.
1이더라도 내가 지금까지 벽을 뚫은적이 없다면 벽을 뚫은 후 다시는 벽을 뚫지 않겠다고 공표하고 방문한다.
따라서 방문할때마다 내가 기존에 벽을 뚫었는지 안뚫었는지 확인을 해야하므로 확인할 수 있는 변수를 큐에 좌표와 함께 넣어준다.
여기까지가 내 아이디어였는데 그 후 수많은 시간초과를 맛보았다.
그리고 그 해결책의 힌트들은
https://www.acmicpc.net/board/view/27386
여기서 얻을 수 있었다.
구현
//c++
#pragma warning (disable:4996)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
int map[1001][1001];
int visited[1001][1001][2];
char tmp[1001];
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };
int n, m;
typedef struct st {
int y;
int x;
int breakWall;
}st;
int bfs() {
std::queue<st>q;
q.push({ 0,0,0 });
visited[0][0][0] = 1;
int cnt = 0;
while (!q.empty()) {
int qSize = q.size();
while (qSize--) {
int y = q.front().y;
int x = q.front().x;
int breakWall = q.front().breakWall;
q.pop();
//std::cout << y << " " << x << std::endl;
if (y == n - 1 && x == m - 1) return cnt + 1;
for (int i = 0; i < 4; i++) {
int yy = y + dy[i];
int xx = x + dx[i];
if (yy >= 0 && xx >= 0 && yy < n && xx < m && visited[yy][xx][breakWall] == 0) {
if (map[yy][xx] == 0) {
q.push({ yy, xx, breakWall });
visited[yy][xx][breakWall] = 1;
}
else if (breakWall == 0) {
q.push({ yy, xx, 1 });
visited[yy][xx][1] = 1;
}
}
}
}
cnt++;
}
return -1;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%s", &tmp);
for (int j = 0; j < m; j++) {
map[i][j] = tmp[j] - '0';
}
}
printf("%d", bfs());
}
최근댓글