题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1026/
题意就是一个迷宫,然后有些位置上有守卫,守卫有一个血量,要多花费血量的时间击败他,要求从(0,0)到(n-1,m-1)的最少用时。显然是用优先队列和bfs实现,因为求解图中每一层结点各自的时间不同,所以我们必须选出时间短的。还有就是递归打印路径的问题,注意一下就好。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define dbg(args) cout<<#args<<":"<<args<<endl; 17 #define inf 0x3f3f3f3f 18 #define maxn 105 19 int n,m,t; 20 int Map[maxn][maxn]; 21 int dir[][2]={0,1,0,-1,1,0,-1,0}; 22 int flag[maxn][maxn]; 23 bool vis[maxn][maxn]; 24 struct node{ 25 int x,y,time; 26 node(int x,int y,int t):x(x),y(y),time(t){} 27 node(){} 28 friend bool operator < ( const node& a,const node& b) 29 { 30 return a.time>b.time;//反向定义操作符,堆顶为time最小的node 31 } 32 }; 33 node cur,nxt; 34 int bfs() 35 { 36 priority_queue<node>q; 37 q.push(node(0,0,0)); 38 vis[0][0]=1; 39 while(!q.empty()) 40 { 41 cur=q.top(); 42 if(cur.x==n-1&&cur.y==m-1)return cur.time; 43 q.pop(); 44 f(i,0,3) 45 { 46 nxt=cur; 47 nxt.x+=dir[i][0]; 48 nxt.y+=dir[i][1]; 49 nxt.time++; 50 if(nxt.x<0||nxt.x>=n||nxt.y<0||nxt.y>=m||Map[nxt.x][nxt.y]==-1)continue; 51 if(!vis[nxt.x][nxt.y]) 52 { 53 vis[nxt.x][nxt.y]=1; 54 flag[nxt.x][nxt.y]=i+1;//保证起点为0,扩展结点方向为大于1 55 if(Map[nxt.x][nxt.y])nxt.time+=Map[nxt.x][nxt.y]; 56 q.push(nxt); 57 } 58 } 59 } 60 return -1; 61 } 62 void print(int x,int y) 63 { 64 if(!flag[x][y])return; 65 int px=x-dir[flag[x][y]-1][0]; 66 int py=y-dir[flag[x][y]-1][1]; 67 print(px,py);//递归打印 68 pf("%ds:(%d,%d)->(%d,%d) ",++t,px,py,x,y); 69 while(Map[x][y]--) 70 pf("%ds:FIGHT AT (%d,%d) ",++t,x,y); 71 } 72 int main() 73 { 74 //freopen("input.txt","r",stdin); 75 //freopen("output.txt","w",stdout); 76 std::ios::sync_with_stdio(false); 77 while(scanf("%d%d",&n,&m)!=EOF) 78 { 79 char c; 80 mem(vis,false); 81 mem(flag,0); 82 f(i,0,n-1) 83 f(j,0,m-1) 84 { 85 scanf(" %c",&c); 86 if(c=='X')Map[i][j]=-1;//将字符地图转化成数字地图 87 else if(c=='.')Map[i][j]=0; 88 else Map[i][j]=c-'0'; 89 } 90 int ans=bfs(); 91 if(ans==-1) 92 { 93 pf("God please help our poor hero. "); 94 } 95 else 96 { 97 pf("It takes %d seconds to reach the target position, let me show you the way. ",ans); 98 t=0; 99 print(n-1,m-1); 100 } 101 pf("FINISH "); 102 } 103 }