思路,广搜,方案1 把加速道具当做空地忽略,从吃豆人开始 到 豆 进行广搜 。 方案2 先(以 吃豆人开始 以 加速道具结束 搜一次)加上 (以 加速道具开始 豆结束 搜一次),两种方案取最优。
wa了多次,因为 和豆 在同一行或同一列 的可以吐舌头,因此必须搜完全部路径 取最小,不能一找到就返回结果。。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define SIZE 22 struct Node { int x, y; double time; }; int n, m; char mat[SIZE][SIZE]; bool vis[SIZE][SIZE]; double tg[SIZE][SIZE]; //记录吐舌头的速度 int Px, Py, Sx, Sy, Bx, By; int dx[] = { -1, 0, 1, 0 }, dy[] = { 0, -1, 0, 1 }; queue<Node> que; void init() { //处理与豆在同一行或者同一列的格子 memset(tg, 0, sizeof(tg)); for (int i = Bx + 1; i < n; i++) { if (mat[i][By] != 'X') tg[i][By] = (i - Bx) * 0.2; else break; } for (int i = Bx - 1; i >= 0; i--) { if (mat[i][By] != 'X') tg[i][By] = (Bx - i) * 0.2; else break; } for (int i = By + 1; i < m; i++) { if (mat[Bx][i] != 'X') tg[Bx][i] = (i - By) * 0.2; else break; } for (int i = By - 1; i >= 0; i--) { if (mat[Bx][i] != 'X') tg[Bx][i] = (By - i) * 0.2; else break; } } bool ok(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; } double bfs(int x, int y, char end, double t) { //(x,y)为起点,end为结束点,t为走一步花的时间 while (!que.empty()) { que.pop(); } memset(vis, false, sizeof(vis)); double ans=10000; Node first; first.x = x, first.y = y, first.time = 0; que.push(first); vis[x][y] = true; while (!que.empty()) { first = que.front(); que.pop(); if (mat[first.x][first.y] == end) { ans = min(ans, first.time); } else if (end == 'B' && tg[first.x][first.y] != 0) { ans = min(ans, first.time + tg[first.x][first.y]); } for (int i = 0; i < 4; i++) { int xx = first.x + dx[i], yy = first.y + dy[i]; if (ok(xx, yy) && mat[xx][yy] != 'X' && !vis[xx][yy]) { Node tmp; tmp.x = xx; tmp.y = yy; tmp.time = first.time + t; que.push(tmp); vis[xx][yy] = true; } } } return ans; } int main() { while (scanf("%d%d", &n, &m) != EOF) { Px = Py = Sx = Sy = Bx = By = -1; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf(" %c", &mat[i][j]); if (mat[i][j] == 'P') Px = i, Py = j; if (mat[i][j] == 'S') Sx = i, Sy = j; if (mat[i][j] == 'B') Bx = i, By = j; } } init(); double ans1 = bfs(Px, Py, 'S', 1); double tmpans = 10000; if (ans1 != 10000) { tmpans = bfs(Sx, Sy, 'B', 0.5); } if (tmpans != 10000) ans1 += tmpans; else ans1 = 100000; double ans2 = bfs(Px, Py, 'B', 1); if (ans2 == 10000) puts("-1"); else printf("%.1lf\n", min(ans1, ans2)); } }