拯救行动-bfs
题意
bfs搜图,不同是要处理可以干掉的守卫
题解
守卫不可以通过更改地图实现消灭,因为这样会影响下一次搜索的查找。所使用的方法是建立步数优先的优先队列来取代普通bfs的队列,每次弹出步数最小的元素进行bfs。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
inline int read()
{
char ch = getchar();int x = 0, f = 1;
while(ch<'0'||ch>'9'){if(ch == '-') f = -1;ch = getchar();}
while('0'<=ch && ch <= '9'){x = x*10+ch-'0';ch = getchar();}
return x*f;
}
ll mod=1e8+7;
ll INF=1e15;
ll Inf=0x3f3f3f3f;
const int N=205;
struct node
{
int x,y,t;
friend bool operator < (node t1,node t2)
{
return t1.t>t2.t;
}
};
char mapp[N][N];
bool vis[N][N];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m;
priority_queue<node> q;
node now,nxt;
int bfs()
{
while(!q.empty())
{
now=q.top();
q.pop();
for(int i=0;i<4;++i)
{
int tx=now.x+dx[i];
int ty=now.y+dy[i];
if(tx<0 || tx>=n || ty<0 || ty>=m || mapp[tx][ty]=='#')
continue;
if(vis[tx][ty])
continue;
if(mapp[tx][ty]=='a')
return now.t+1;
if(mapp[tx][ty]=='@')
{
nxt.x=tx;
nxt.y=ty;
nxt.t=now.t+1;
q.push(nxt);
vis[nxt.x][nxt.y]=1;
}
if(mapp[tx][ty]=='x')
{
nxt.x=tx;
nxt.y=ty;
nxt.t=now.t+2;
q.push(nxt);
vis[nxt.x][nxt.y]=1;
}
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
cin>>mapp[i][j];
if(mapp[i][j]=='r')
{
now.x=i;
now.y=j;
now.t=0;
q.push(now);
vis[now.x][now.y]=1;
}
}
}
int ans=bfs();
if(ans==-1)
cout<<"Impossible"<<endl;
else
cout<<ans<<endl;
return 0;
}