题意:给你一个迷宫,迷宫有开始节点和结束节点,问你从开始走到结束的最小时间,其中,#代表这个点有毒气,身上必须带着氧气瓶才行,B代表每次进入这个点可以带一个氧气瓶,最多身上带五个,P代表进入这个点加速,不耗费时间
解题思路:就是bfs+优先队列,就是氧气瓶的地方麻烦点,我们只需要对于每个点,用一个多余的状态标记进入这个点身上氧气瓶的数量就可以了
代码:
#include<bits/stdc++.h> using namespace std; struct node { int x,y,step,cnt; node(int _x=0,int _y=0,int _step=0,int _cnt=0):x(_x),y(_y),step(_step),cnt(_cnt){} friend bool operator<(node a,node b) { return a.step>b.step; } }tmp,now; char s[110][110]; int n,m,sx,sy; int next1[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; int visit[110][110][10]; int bfs(int x,int y) { priority_queue<node>que; que.push(node(x,y,0,0)); while(!que.empty()) { now=que.top();que.pop(); if(s[now.x][now.y]=='T') return now.step; for(int i=0;i<4;i++) { tmp.x=now.x+next1[i][0];tmp.y=now.y+next1[i][1]; if(tmp.x<1||tmp.x>n||tmp.y<1||tmp.y>m) continue; if(s[tmp.x][tmp.y]=='B') { tmp.cnt=min(5,now.cnt+1);tmp.step=now.step+1; if(!visit[tmp.x][tmp.y][tmp.cnt]) { visit[tmp.x][tmp.y][tmp.cnt]=1; que.push(tmp); } } else if(s[tmp.x][tmp.y]=='P') { tmp.cnt=now.cnt;tmp.step=now.step; if(!visit[tmp.x][tmp.y][tmp.cnt]) { visit[tmp.x][tmp.y][tmp.cnt]=1; que.push(tmp); } } else if(s[tmp.x][tmp.y]=='#') { tmp.cnt=now.cnt-1;tmp.step=now.step+2; if(tmp.cnt<0) continue; if(!visit[tmp.x][tmp.y][tmp.cnt]) { visit[tmp.x][tmp.y][tmp.cnt]=1; que.push(tmp); } } else { tmp.cnt=now.cnt;tmp.step=now.step+1; if(!visit[tmp.x][tmp.y][tmp.cnt]) { visit[tmp.x][tmp.y][tmp.cnt]=1; que.push(tmp); } } } } return -1; } int main() { while(cin>>n>>m&&n&&m) { memset(visit,0,sizeof(visit)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>s[i][j];if(s[i][j]=='S'){sx=i;sy=j;} } int ans=bfs(sx,sy); cout<<ans<<endl; } }