拯救行动
题目描述: 现假设骑士可以向上、下、左、右四个方向移动,每移动一个位置需要 1 个单位时间,杀死一个守卫需要花费额外的 1 个单位时间。同时假设骑士足够强壮,有能力杀死所有的守卫。
给定牢房矩阵,公主、骑士和守卫在矩阵中的位置,请你计算拯救行动成功需要花费最短时间。
输入格式 1、两个整数代表 N 和 M, (N,M≤200). 2、随后 N 行,每行有 M 个字符。"@" 代表道路,“a” 代表公主,“r” 代表骑士,“x” 代表守卫, “#” 代表墙壁。
输出格式 如果拯救行动成功,输出一个整数,表示行动的最短时间。 如果不可能成功,输出 “Impossible”。
输出时每行末尾的多余空格,不影响答案正确性
样例输入 7 8 #@#####@ #@a#@@r@ #@@#x@@@ @@#@@#@# #@@@##@@ @#@@@@@@ @@@@@@@@ 样例输出 13
解题思路:
此题在走到x和@时的花费是不同的,但bfs是按顺序进行搜索的,因此可能搜索到结果时的时间不是最短,此时就需要用到优先队列,时间短的先出队
代码:
#include <iostream> #include <queue> using namespace std; int n,m,f,sx,sy,ex,ey; char map[205][205]; int flag[205][205]; int tr[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; struct node { int x; int y; int s; node (int xx,int yy,int ss) { x=xx; y=yy; s=ss; } friend bool operator < (node a,node b) { return a.s>b.s; } }; int main() { cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>map[i][j]; if(map[i][j]=='r') { sx=i; sy=j; } if(map[i][j]=='a') { ex=i; ey=j; } } } priority_queue<node> q; node temp(sx,sy,0); q.push(temp); flag[sx][sy]=1; while(!q.empty()) { temp=q.top(); q.pop(); for(int i=0;i<4;i++) { int tx=temp.x+tr[i][0]; int ty=temp.y+tr[i][1]; int ss=temp.s+1; if(tx>0&&tx<=n&&ty>0&&ty<=m) { if(tx==ex&&ty==ey) { f=1; cout<<ss<<endl; break; } if(!flag[tx][ty]&&map[tx][ty]=='@') { q.push(node(tx,ty,ss)); flag[tx][ty]=1; } if(!flag[tx][ty]&&map[tx][ty]=='x') { q.push(node(tx,ty,ss+1)); flag[tx][ty]=1; } } } if(f==1) break; } if(f==0) cout<<"Impossible"<<endl; return 0; }