Jzoj P5793 小S練跑步___bfs+dp
阿新 • • 發佈:2018-12-13
題目大意:
給出一副n*m的圖,每個點都有限制不能走的方向,不能越界,遇到障礙後會停止,問從點(1,1)走到點(n,m)的最少轉彎次數。
n,m≤500
分析:
設表示到達了點下一步走的方向為時的最少轉彎次數, 然後用bfs去更新即可
程式碼:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define N 505 using namespace std; const int inf = 0x3f3f3f; const int px[4] = {-1, 0, 0, 1}; const int py[4] = {0, -1, 1 ,0}; queue <int> dx, dy, nt, num; int f[N][N][5], n, m; bool a[N][N][5]; char s[N]; bool check(int mx, int my) { if (mx < 1 || mx > n || my < 1 || my > n) return 1; if (a[mx][my][4]) return 1; return 0; } int main() { freopen("run.in","r",stdin); freopen("run.out","w",stdout); scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%s", s + 1); for (int j = 1; j <= m; j++) { if (s[j] == 'U') a[i][j][0] = 1; if (s[j] == 'L') a[i][j][1] = 1; if (s[j] == 'R') a[i][j][2] = 1; if (s[j] == 'D') a[i][j][3] = 1; if (s[j] == 'S') a[i][j][4] = 1; for (int k = 0; k < 4; k++) f[i][j][k] = inf; } } for (int i = 0; i < 4; i++) if (!a[1][1][i]) { f[1][1][i] = 0; dx.push(1), dy.push(1), nt.push(i); while (dx.size()) { int gc = nt.front(); int gx = dx.front(); int gy = dy.front(); dx.pop(), dy.pop(), nt.pop(); int cx = gx + px[gc]; int cy = gy + py[gc]; if (check(cx, cy)) continue; for (int j = 0; j < 4; j++) { if (a[cx][cy][j]) continue; int x = f[gx][gy][gc]; if (j != gc) x++; if (f[cx][cy][j] > x) { f[cx][cy][j] = x; dx.push(cx), dy.push(cy), nt.push(j); } } } } int ans = min(f[n - 1][m][3], f[n][m - 1][2]); if (ans != inf) printf("%d\n", ans); else printf("No Solution\n"); return 0; }