题目:
思路:
1.先根据输入的机器辐射值对房屋内的点进行辐射标记,若在辐射范围内,则标记为-1,不在辐射范围的标记为0;
2.从出发点开始进行广度优先遍历,并不断的更新当前路径长,结束条件为到达出口或遍历结束;
注意:ray数组有两个作用,刚开始用来标记辐射值,开始遍历后用来记录当前路径长;
代码:
#include <iostream>
using namespace std;
int adj[4][2]={0,1,0,-1,1,0,-1,0};//用来四个方向遍历
typedef struct{
int x,y;
}room;
void process(int n, int m, int i, int j, int**r)
{
if (i>=0 && i<n && j>=0 && j<m)
{
r[i][j]=-1;//辐射标记
}
}
int BFS(int n, int m, room b,room e,int** ray)
{
queue<room> Q;
room beginroom;
beginroom.x=b.x;
beginroom.y=b.y;
if (ray[b.x][b.y]==-1)
{
return -1;
}
Q.push(beginroom);
while(!Q.empty())
{
room curroom = Q.front();
Q.pop();
if (curroom.x==e.x && curroom.y==e.y)
return ray[e.x][e.y];//到达出口
for(int i=0;i<4;i++)
{
int tx=curroom.x + adj[i][0];
int ty=curroom.y + adj[i][1];
if (tx>=0 && tx<n && ty>=0 && ty<m)
{
if (ray[tx][ty]!=-1)//安全区
{
room nextroom;
nextroom.x=tx;
nextroom.y=ty;
if(ray[tx][ty]==0)//之前未访问过
ray[tx][ty]=ray[curroom.x][curroom.y]+1;
else//之前访问过
ray[tx][ty]=min(ray[tx][ty],ray[curroom.x][curroom.y]+1);
Q.push(nextroom);
}
}
}
}
return -1;//没有找到出口
}
int main( )
{
int n;//行
while (cin>>n)
{
int m;//列
cin>>m;
room b,e;
cin>>b.x;
cin>>b.y;
cin>>e.x;
cin>>e.y;
int **ray = new int*[n];//辐射数组
int v;
for (int i=0;i<n;i++)
{
ray[i] = new int[m]();
for (int j=0;j<m;j++)
{
cin>>v;
for (int k=0;k<v;k++)
{
process(n,m,i+k,j,ray);
if (v==1)
break;
process(n,m,i-k,j,ray);
process(n,m,i,j+k,ray);
process(n,m,i,j-k,ray);
}
}
}
int ans = BFS(n,m,b,e,ray);
cout<<ans<<endl;
}
return 0;
}