飞越原野
Description
在一片广阔的土地上,有一个鸟人,他需要从这里穿过原野,回到基地。这片原野上,有平地(P)、有湖泊(L),因为鸟人可以飞,所以呢,有的时候,他可以飞越湖泊。现在,鸟人需要用最快的时间,回到基地。
假设原野是一个m*n的矩阵,有两种地形,用P和L表示。鸟人只能停留在平地上。他目前处在(1,1)这个位置,而目的地是(m,n)。他可以向上下左右四个方向移动,或者飞行。每移动一格需要1个单位时间。而飞行无论飞多远,都只需要1个单位时间。飞行的途中不可以变方向,也就是说飞行也只能是上下左右四个方向。并且一次飞行最终必须降落在平地上。当然,受到能量的限制,鸟人不能无限制的飞行,他总共最多可以飞行的距离为D。
假设原野是一个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
思路
有两种移动方式
步行:上下左右移动一格,只能通过平原,“能量”不变。
飞行:上下左右移动任意格,可以穿越湖泊和平原,但是起点和终点必须是平原,“能量”减少飞行的长度。
两种移动方式要分开写,步行就是通常bfs的那种拓展节点的方式,飞行需要在方向上加上一个循环变量j(飞行距离)。
注意总共最多可以飞行的距离(能量)为D,不是每次可以飞的距离。
代码示例
#include<iostream>
#include<queue>
#define MAX 101
using namespace std;
char map[MAX][MAX];
int vis[MAX][MAX][MAX];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
int m,n,flag,val,d;
struct point{//将坐标看做结构体在队列中操作
int x,y,fei,num;
point(int xx,int yy,int dd,int nn){
x=xx;
y=yy;
fei=dd;
num=nn;
}
};
queue<point> q;//声明结构体点队列
bool visit(int x,int y,int fei){//判断是否能visit
if(x>=0&&x<m&&y>=0&&y<n&&map[x][y]=='P'&&vis[x][y][fei]==0){
return true;
}
else return false;
}
void bfs(){
q.push(point(0,0,d,0));//将起始点放入队列
vis[0][0][d]=1;
while(!q.empty())//只要队列不空
{
point p=q.front();
q.pop();
if(p.x==m-1&&p.y==n-1){
flag=1;//找到
val=p.num;
break;
}
for(int i=0;i<4;++i){//走 (只能走P)
if(visit(p.x+dir[i][0],p.y+dir[i][1],p.fei)){
q.push(point(p.x+dir[i][0],p.y+dir[i][1],p.fei,p.num+1));
vis[p.x+dir[i][0]][p.y+dir[i][1]][p.fei]=1;
}
}
for(int i=0;i<4;++i){//飞 (有fei的限制)
for(int j=2;j<=p.fei;++j){
if(visit(p.x+dir[i][0]*j,p.y+dir[i][1]*j,p.fei-j)){
q.push(point(p.x+dir[i][0]*j,p.y+dir[i][1]*j,p.fei-j,p.num+1));
vis[p.x+dir[i][0]*j][p.y+dir[i][1]*j][p.fei-j]=1;
}
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin>>m>>n>>d;
for(int i=0;i<m;++i){
cin>>map[i];
}
bfs();
if(flag==1) cout<<val<<endl;
else cout<<"impossible"<<endl;
return 0;
}