-
백준 1175번 배달PS 2021. 3. 29. 23:52
<접근방법>
중복체크를 위한 상태공간을 정의해야 합니다.
탐색이 발산적으로 이루어지므로 목표지점 1을 방문할 때, 목표지점 2의 경로를 지나갈 수 있습니다.
따라서 이 두 개는 따로 체크되어야 합니다.
그리고 방향은 매시간 달라지므로 어떤 방향으로 나가냐(혹은 들어오냐)에 따라 체크가 따로 되어야 합니다.
따라서 상태공간을 이루는 요소로 좌표, 방향, 1의 방문 여부, 2의 방문 여부 입니다.
<코드>
#include <iostream> #include <algorithm> #include <queue> #include <vector> #include <string> #include <set> using namespace std; #define MAX 50+1 struct point { int y, x, dir, cnt; bool cVisited = false, dVisited = false; }; int n, m, sy, sx; char map[MAX][MAX]; bool visit[MAX][MAX][5][2][2]; int dy[] = { -1, 0, 1, 0 }; int dx[] = { 0, 1, 0, -1 }; void print_map() { for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << map[i][j] << ' '; } cout << '\n'; } cout << '\n'; } bool isRange(int y, int x) { if (y < 0 || y >= n || x < 0 || x >= m) return false; return true; } void input() { cin >> n >> m; for (int i = 0; i < n; i++) { cin >> map[i]; } int cnt = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] == 'S') { sy = i; sx = j; } if (map[i][j] == 'C') { cnt++; if (cnt == 2) { map[i][j] = 'D'; } } } } //print_map(); } int bfs() { queue<point> q; q.push({ sy, sx, -1, 0, 0, 0 }); visit[sy][sx][4][0][0] = true; while (!q.empty()) { point t = q.front(); q.pop(); if (t.cVisited && t.dVisited) { return t.cnt; } for (int i = 0; i < 4; i++) { int ty = t.y + dy[i]; int tx = t.x + dx[i]; int cnt = t.cnt + 1; bool C = t.cVisited; bool D = t.dVisited; if (t.dir == i) continue; if (!isRange(ty, tx)) continue; if (map[ty][tx] == '#') continue; if (visit[ty][tx][i][C][D]) continue; if (map[ty][tx] == 'C') { C = true; } if (map[ty][tx] == 'D') { D = true; } visit[ty][tx][i][C][D] = true; q.push({ ty, tx, i, cnt, C, D }); } } return -1; } int main() { input(); cout << bfs() << '\n'; return 0; }
'PS' 카테고리의 다른 글
백준 11729번 하노이 탑 이동순서 (0) 2021.04.02 백준 1074 Z (0) 2021.04.02 백준 9328번 열쇠 (0) 2021.03.29 백준 16952번 체스판 여행 (0) 2021.03.29 백준 16920번 확장 게임 (0) 2021.03.29