题意:n*m的迷宫,从(0,0)到(n-1,m-1),遇到怪物停留怪物所在方格中的数字个单位时间,求最短时间并打印路径;
思路:用bfs先搜最短路,搜最短路时一定要用优先队列,不然结果不对;在通过保存上一步的方法保存路径,到达终点时,将路径查询出来,遇到怪物是位置不变;
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; int n,m,s1,s2,e1,e2; char mm[505][505]; int vis[505][505]; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; struct node { int x,y,t; bool operator<(const node&xx)const { return t>xx.t; } }; struct lujin { int x1,y1,x2,y2; }record[505]; node pre[505][505]; int quan[505][505],route[505][505]; int bfs() { priority_queue<node>q; vis[s1][s2]=1; node cur,now; node s; s.x=s1;s.y=s2;s.t=0; q.push(s); while(!q.empty()) { cur=q.top(); q.pop(); for(int i=0;i<4;i++) { now.x=cur.x+dir[i][0]; now.y=cur.y+dir[i][1]; now.t=cur.t+1; if(now.x<0||now.x>=n||now.y<0||now.y>=m||vis[now.x][now.y]||mm[now.x][now.y]==‘X‘) continue; if(mm[now.x][now.y]>=‘1‘&&mm[now.x][now.y]<=‘9‘) { now.t+=mm[now.x][now.y]-‘0‘; } if(now.x==(n-1)&&now.y==(m-1))//到达终点,倒退回去找路径 { int num=0,temp1,temp2; e1=now.x;e2=now.y; pre[now.x][now.y]=cur; while(e1!=0||e2!=0)//或的关系!!不是与,小bug调试了很久。。。 { if(mm[e1][e2]>=‘1‘&&mm[e1][e2]<=‘9‘) { for(int j=0;j<mm[e1][e2]-‘0‘;j++) { record[now.t-num].x1=pre[e1][e2].x; record[now.t-num].y1=pre[e1][e2].y; record[now.t-num].x2=e1; record[now.t-num].y2=e2; num++; } } record[now.t-num].x1=pre[e1][e2].x; record[now.t-num].y1=pre[e1][e2].y; record[now.t-num].x2=e1; record[now.t-num].y2=e2; temp1=pre[e1][e2].x; temp2=pre[e1][e2].y; //printf("(%d,%d)->(%d,%d)\n",e1,e2,temp1,temp2); e1=temp1;e2=temp2; num++; } return now.t; } vis[now.x][now.y]=1; q.push(now); pre[now.x][now.y]=cur;//保存上一步 } } return -1; } int main() { int i,j,k,ans; while(scanf("%d%d",&n,&m)!=EOF) { memset(mm,0,sizeof(mm)); memset(vis,0,sizeof(vis)); memset(quan,0,sizeof(quan)); memset(pre,0,sizeof(pre)); memset(route,0,sizeof(route)); memset(record,0,sizeof(record)); for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf(" %c",&mm[i][j]); s1=0,s2=0; } } ans=bfs(); if(ans==-1) printf("God please help our poor hero.\n"); else printf("It takes %d seconds to reach the target position, let me show you the way.\n",ans); if(ans!=-1) { for(i=1;i<=ans;i++) { printf("%ds:",i); if(record[i-1].x2==record[i].x2&&record[i-1].y2==record[i].y2) printf("FIGHT AT (%d,%d)\n",record[i].x2,record[i].y2); else printf("(%d,%d)->(%d,%d)\n",record[i].x1,record[i].y1,record[i].x2,record[i].y2); } } printf("FINISH\n"); } }
时间: 2024-11-11 13:08:19