题面:
在一片广阔的土地上,有一个鸟人,他需要从这里穿过原野,回到基地。这片原野上,有平地(P)、有湖泊(L),因为鸟人可以飞,所以呢,有的时候,他可以飞越湖泊。现在,鸟人需要用最快的时间,回到基地。
假设原野是一个m*n的矩阵,有两种地形,用P和L表示。鸟人只能停留在平地上。他目前处在(1,1)这个位置,而目的地是(m,n)。他可以向上下左右四个方向移动,或者飞行。每移动一格需要1个单位时间。而飞行无论飞多远,都只需要1个单位时间。飞行的途中不可以变方向,也就是说飞行也只能是上下左右四个方向。并且一次飞行最终必须降落在平地上。当然,受到能量的限制,鸟人不能无限制的飞行,他总共最多可以飞行的距离为D。
Input
第一行是三个整数,m,n,D,三个数都不超过100,下面是一个m*n的矩阵,表示原野
Output
一个整数,为最短时间,如果无法到达,则输出“impossible”
Sample Input
4 4 2
PLLP
PPLP
PPPP
PLLP
Sample Output
5
大致思路:
通过一个节点,记录当前的x,y坐标,所用时间,剩余的可飞行距离。
开一个三维的visit数组记录走过的路径,因为需要额外的维度来记录剩余的飞行能力。因为,同样是到达一个点,不同的飞行剩余距离,所得答案有可能不同。
利用BFS进行搜索。不同的是,一般的BFS只需要枚举4个方向走一步的情况,而这个题则需要多枚举飞行的情况。也就是说,枚举每一种可能,走路,飞行2格、3格···一直到最大剩余飞行距离。对于每一个节点都这么操作。就可以得到答案。
P.S. 手写队列比用STL快,但需要将队列开大一点。(10w不够,应该是状态数大于10w。我开50w过了)。
代码:
#include<iostream>
#include<cstring>
using namespace std;
char mp[110][110];
int n,m,d;
bool visit[110][110][110];
typedef struct{
int x,y,d,time;
}Node;
const int maxn=500000;
typedef struct{
Node a[maxn];
int head,tail;
}Que;
bool check(int x,int y,int d)//判断能不能到这里去
{
if(x<1||x>m||y<1||y>n)
return false;
if(visit[x][y][d]||mp[x][y]=='L')
return false;
return true;
}
Que q;
int main()
{
ios::sync_with_stdio(false);
memset(visit,false,sizeof(visit));
int dis1[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int ans=0;
bool succ=false;
cin>>m>>n>>d;
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j)
cin>>mp[i][j];
Node a;
a.y=a.x=1;
a.d=d;
a.time=0;
q.head=0;
q.tail=0;
q.a[q.tail++]=a;
mp[1][1]='L';
while(q.tail!=q.head)
{
Node b=q.a[q.head++];
q.head%=maxn;
if(b.x==m&&b.y==n){
ans=b.time;
succ=true;
break;
}
int dx,dy,dd;
for(int i=0;i<4;++i){//枚举走路的所有情况
dx=b.x+dis1[i][0];
dy=b.y+dis1[i][1];
dd=b.d;
if(check(dx,dy,dd)){
Node c;
c.x=dx;c.y=dy;c.d=dd;c.time=b.time+1;
q.a[q.tail++]=c;
q.tail%=maxn;
visit[dx][dy][dd]=true;
}
}
for(int i=0;i<4;++i){
for(int j=2;j<=b.d;++j){//枚举飞行的所有情况
dx=b.x+dis1[i][0]*j;
dy=b.y+dis1[i][1]*j;
dd=b.d-j;
if(check(dx,dy,dd)){
Node c;
c.x=dx;c.y=dy;c.d=dd;c.time=b.time+1;
q.a[q.tail++]=c;
q.tail%=maxn;
visit[dx][dy][dd]=true;
}
}
}
}
if(succ)
cout<<ans<<endl;
else
cout<<"impossible"<<endl;
return 0;
}