题意:图中Y代表起点,T代表终点,S代表铁墙,不可被击毁也不可被通过,B代表木墙,可以被击毁,击毁后可以通过,R代表河流,不可击毁也不可通过,E代表可通过。
击毁木墙会消耗一步,问最少多少步能从起点走到终点。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
//优先队列广搜
const int maxn=305;
const int INF=0x3f3f3f3f;
char map[maxn][maxn];
int vis[maxn][maxn];
int dis[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
int N,M;
int star_x,star_y;
int end_x,end_y;
struct node
{
int x;
int y;
int time;
friend bool operator <(node n1,node n2)
{
return n1.time>n2.time;
}
};
int BFS(int star_x,int star_y)
{
priority_queue<node>q;
node star;
star.time=0;
star.x=star_x;
star.y=star_y;
memset(vis,0,sizeof(vis));
vis[star_x][star_y]=1;
q.push(star);
while(!q.empty())
{
star=q.top();
q.pop();
for(int i=0; i<4; i++)
{
node end;
end=star;
end.x+=dis[i][0];
end.y+=dis[i][1];
if(end.x>=1&&end.x<=N&&end.y>=1&&end.y<=M&&vis[end.x][end.y]==0&&map[end.x][end.y]!='S'&&map[end.x][end.y]!='R')
{
// printf("%d %d\n",end.x,end.y);
if(map[end.x][end.y]=='E')
{
end.time++;
vis[end.x][end.y]=1;
q.push(end);
}
else if(end.x==end_x&&end.y==end_y)
{
end.time++;
return end.time;
}
else if(map[end.x][end.y]=='B')
{
end.time++;
end.time++;//这里做了改动
vis[end.x][end.y]=1;
q.push(end);
}
}
}
}
// for(int i=1; i<=N; i++)
// {
// for(int j=1; j<=M; j++)
// printf("%c ",map[i][j]);
// printf("\n");
// }
return -1;
}
int main()
{
while(~scanf("%d%d",&N,&M)&&N&&M)
{
for(int i=1; i<=N; i++)
{
getchar();
for(int j=1; j<=M; j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='Y')
{
star_x=i;
star_y=j;//这里可能有问题
}
else if(map[i][j]=='T')
{
end_x=i;
end_y=j;
}
}
// getchar();
}
printf("%d\n",BFS(star_x,star_y));
}
return 0;
}