原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
一. 题意:英雄去救公主,起点(0, 0), 终点(row - 1, col - 1), ‘X'不能走,遇到数字停下来打怪,数字多少就要打多少秒,求最快到达时间。
二. 解题思路:看结构体怎么定义的就直接知道我怎么记录路径的, 记得路径的数组要开大一些。
三. AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int INF = 99999; int row, col, couTime; char maze[101][101]; int movei[] = {-1, 1, 0, 0}; int movej[] = {0, 0, -1, 1}; char direction[] = {'u', 'd', 'l', 'r'}; bool check(int i, int j) { if(i < 0 || i >= row || j < 0 ||j >= col || 'X' == maze[i][j]) return false; return true; } struct node { int i, j, time; char path[10000]; friend bool operator < (node a, node b){ return a.time > b.time;} }; node cur, Next; bool bfs() { priority_queue <node> que; int dir, endTime; cur.i = 0, cur.j = 0, cur.time = 0; que.push(cur); while(!que.empty()){ cur = que.top(); que.pop(); if(cur.i == row - 1 && cur.j == col - 1) return true; for(dir = 0; dir < 4; dir++){ Next.i = cur.i + movei[dir]; Next.j = cur.j + movej[dir]; Next.time = cur.time; strcpy(Next.path, cur.path); if(check(Next.i, Next.j)){ Next.path[Next.time] = direction[dir]; if(maze[Next.i][Next.j] >= '0' && maze[Next.i][Next.j] <= '9'){ endTime = cur.time + maze[Next.i][Next.j] -'0' + 1; Next.time++; for(; Next.time < endTime; Next.time++) Next.path[Next.time] = 'f'; } else{ Next.time++; } maze[Next.i][Next.j] = 'X'; que.push(Next); } } } return false; } void printPath() { printf("It takes %d seconds to reach the target position, let me show you the way.\n", cur.time); int i, iPos = 0, jPos = 0; for(i = 0; i < cur.time; i++){ printf("%ds:", i + 1); switch(cur.path[i]) { case 'f': printf("FIGHT AT (%d,%d)\n", iPos, jPos); break; case 'u': printf("(%d,%d)->", iPos, jPos); iPos = iPos - 1; printf("(%d,%d)\n", iPos, jPos); break; case 'd': printf("(%d,%d)->", iPos, jPos); iPos = iPos + 1; printf("(%d,%d)\n", iPos, jPos); break; case 'l': printf("(%d,%d)->", iPos, jPos); jPos = jPos - 1; printf("(%d,%d)\n", iPos, jPos); break; case 'r': printf("(%d,%d)->", iPos, jPos); jPos = jPos + 1; printf("(%d,%d)\n", iPos, jPos); break; } } } int main() { //freopen("in.txt", "r", stdin); int i, j; while(cin>>row>>col){ for(i = 0; i < row; i++) cin>>maze[i]; maze[0][0] = 'X'; if(!bfs()) cout<<"God please help our poor hero.\n"; else printPath(); cout<<"FINISH\n"; } }
四. 总结:这题让我知道了求最短路径要广搜(优先队列),求特殊解或者是全部遍历用深搜。开始傻傻用深搜,然后超时了,然而广搜还是600多ms。囧!
五. 做完另一道BFS后再回来总结一下:
1. 广搜求最短路径,优先队列的优先级就是路径。
也就是说,要把路径,本题也就是时间,绑定在一个结构体里面。
2. 其次,不要忘记标记走过的路啊啊啊,刚刚忘记标记然后就搞笑了。