题目描述
假设你在一个n*n的冰面上,并且你想到达这个冰面的某处,可是由于冰面太滑了,所以当你向某个方向出发后,你没有办法使自己停下来直到你碰到了某个障碍物——因为你可以抓住障碍物使得你的身体停止运动。
因为你已经知道了整个地图,所以你决定在行动之前先计算出最快可到达目标的路线,使得你可以不用走太多冤枉路,这时你决定编程解决这个问题……
输入
第一行包括一个正整数n(n<=1000)
以下n行,每行包括n个数字(0或1),0表示该点为空地可以滑行,1表示该点为障碍物(障碍物无法穿过)。保证最外圈的地形为障碍物,也就是你无法离开这个地图。
接下来1行包括2个整数x,y(1<=x,y<=n),表示一开始你处于坐标(x,y)
再接下来1行包括2个整数x2,y2(1<=x2,y2<=n),表示你想要到达的目标为(x2,y2)
输出
只有一个整数t,表示能到达目标的最短时间(假设每经过一次滑行需要花费1单位的时间,无论这次滑行距离的长短)。所谓到达目标要求必须停留在(x2,y2),也就是你不能在到达之后被迫滑向下一个点。当你无法到达目标点时,你只须输出一行字符串’impossible’。
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,q[1000510][5],sum,h,t,x,y,xx,yy,xxx,yyy;//n map大小 q点的属性 h头指针 t尾指针
int a[1010][1010];
bool vis[1010][1010];//map
int dx[5]= {0,0,1,-1};//坐标
int dy[5]= {1,-1,0,0};
int main()
{
scanf("%d",&n);//输入地图大小
for(int i=1;i<=n;i++)//输入地图
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
scanf("%d%d%d%d",&x,&y,&xx,&yy);//和终点
if(x==y&&xx==yy)
{
cout<<"0";
return 0;
}
if(a[xx+1][yy]==0&&a[xx][yy+1]==0&&a[xx-1][yy]!=1&&a[xx][yy-1]==0)
{
printf("impossible");
return 0;
}
h=1;//初始化
t=1;
q[1][1]=x;
q[1][2]=y;
q[1][3]=0;
while(h<=t)//宽搜
{
for(int i=0;i<4;i++)
{
if(xxx==xx&&yyy==yy)//到终点输出
{
printf("%d",q[t][3]);
return 0;
}
xxx=q[h][1];
yyy=q[h][2];//printf("%d ",a[xxx+dx[i]][yyy+dy[i]]);
while(a[xxx+dx[i]][yyy+dy[i]]==0)//范围
{
xxx+=dx[i];
yyy+=dy[i];
}
if(vis[xxx][yyy]==0)
{
t++;//尾数++
q[t][1]=xxx;
q[t][2]=yyy;
q[t][3]=q[h][3]+1;
vis[xxx][yyy]=1;//printf("%d",q[t][3]);
}
}
h++;
}
printf("impossible");
return 0;
}