然后我又准备用最短路的思想模拟,但是还是准备在上面的基础上改一下,于是每一个点出队我也标记了下,这样保证了终点可以多次遍历到
但是这样一来就无法解决跳出 BFS 问题,于是我想到每一个点最多被上下左右的点走一次,那么是不是标记每一个点最多入队四次就可以了呢?
样例同样出来了,结果还是 WA 。。。
想了下:可能是我虽然标记了入队四次,但是可能这四次都是由同一个点到达的,那么也和标记一次没有分别了,还是无法解决上面的更新最短时间问题。
所以:最终还是只能按照最短路的思想遍历。
很裸的题目了,本来只是打算练下手,结果还是做了很久。菜鸟要努力 Fighting !!!Come on
code:
#include#include #include #include #include using namespace std; const int maxn = 110; const int INF = maxn*maxn*10; int map[maxn][maxn]; //记录图 int vis[maxn][maxn]; //标记入队 char str[maxn]; int n,m; int dir[4][2] = {0,1, 0,-1, -1,0, 1,0}; //定义优先队列:对于入队了的点,先出队的是时间少的,那么第一个到达终点的就是结果 struct Node{ int x,y; //当前到达的点 int time; //耗费的时间 bool operator < (const Node &b) const{ return b.time < time; } }; //每一个点的前驱, 由于是逆向搜索的, 所以记录的其实是当前点的下一个点了 struct Pre{ int px, py; }pre[maxn][maxn]; void bfs() { Node now, next; priority_queue q; while(!q.empty()) q.pop(); now.x = n; now.y = m; //从终点走向起点 now.time = map[n][m]; //注意:终点也可能会有怪兽 pre[n][m].px = -1; //输出边界 q.push(now); memset(vis, 0, sizeof(vis)); //为方便快速输出路径, 从终点往起点找 vis[n][m] = 1; //标记终点入队 while(!q.empty()) { now = q.top(); q.pop(); if(now.x == 1 && now.y == 1) //一旦到达起点 { printf("It takes %d seconds to reach the target position, let me show you the way.\n", now.time); int time = 1; int x = now.x, y = now.y; //当前的位置 int nx = pre[x][y].px, ny = pre[x][y].py; //下一个位置 while(pre[x][y].px != -1) //不停的找前驱 { printf("%ds:(%d,%d)->(%d,%d)\n", time++, x-1, y-1, nx-1, ny-1); while(map[nx][ny]--) //如果有怪兽 { printf("%ds:FIGHT AT (%d,%d)\n", time++, nx-1, ny-1); } x = nx; y = ny; //继续查找下一个点 nx = pre[x][y].px, ny = pre[x][y].py; } printf("FINISH\n"); return; //结束 } for(int i = 0; i < 4; i++) { next.x = now.x+dir[i][0]; next.y = now.y+dir[i][1]; if(map[next.x][next.y] >= 0 && !vis[next.x][next.y]) //当前点可以走,并且没有入队过 { vis[next.x][next.y] = 1; //标记入队 next.time = now.time + 1 + map[next.x][next.y]; pre[next.x][next.y].px = now.x; //前驱记录 pre[next.x][next.y].py = now.y; q.push(next); } } } printf("God please help our poor hero.\n"); //不能到达 printf("FINISH\n"); return; } int main() { while(scanf("%d%d", &n,&m) != EOF) { gets(str); for(int i = 0; i <= n+1; i++) //周围加边 for(int j = 0; j <= m+1; j++) map[i][j] = -1; char c; for(int i = 1; i <= n; i++) //输出的时候注意 -1 处理下 { for(int j = 1; j <= m; j++) { scanf("%c", &c); if(c != 'X') { if(c == '.') map[i][j] = 0; else map[i][j] = c-'0'; } } gets(str); } bfs(); } return 0; }