飞跃原野(三维bfs)

Problem Description
勇敢的法里奥出色的完成了任务之后,正在迅速地向自己的基地撤退。但由于后面有着一大群追兵,所以法里奥要尽快地返回基地,否则就会被敌人逮住。

终于,法里奥来到了最后的一站:泰拉希尔原野,穿过这里就可以回到基地了。然而,敌人依然紧追不舍。不过,泰拉希尔的地理条件对法里奥十分有利,众多的湖泊随处分布。敌人需要绕道而行,但法里奥还是决定找一条能尽快回到基地的路。
 
假设泰拉希尔原野是一个m*n的矩阵,它有两种地形,P表示平,L表示湖泊,法里奥只能停留在平地上。他目前的位置在左上角(1,1)处,而目的地为右下角的(m,n)。法里奥可以向前后左右4个方向移动或飞行,每移动1格需要1单位时间。而飞行的时间主要花费在变形上,飞行本身时间消耗很短,所以无论一次飞行多远的距离,都只需要1单位时间。飞行的途中不能变向,并且一次飞行最终必须要降落到平地上。当然,由于受到能量的限制,法里奥不能无限制飞行,他总共最多可以飞行的距离为D。在知道了以上的信息之后,请你帮助法里奥计算一下,他最快到达基地所需要的时间。
Input
第一行是3个整数,m(1≤m≤100),n(1≤n≤100),D(1≤D≤100)。表示原野是m*n的矩阵,法里奥最多只能飞行距离为D。接下来的m行每行有n个字符,相互之间没有空格。P表示当前位置是平地,L则表示湖泊。假定(1,1)和(m,n)一定是平地。
Output
一个整数,表示法里奥到达基地需要的最短时间。如果无法到达基地,则输出impossible。
Sample Input
4 4 2
PLLP
PPLP
PPPP
PLLP
Sample Output
5
Hint
 
Source

 

在bfs的基础上多出一维用来标记表示剩余的飞行距离

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int n,m,d;
struct node
{
    int x,y;
    int step;
    int left;
};
char Map[105][105];
int vis[105][105][105];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
bool check(int x,int y)
{
    if(x>=0&&x<m&&y>=0&&y<n)
    {
        return true;
    }
    else
    {
        return false;
    }
}
int BFS(int  x,int y )
{
 node start ;
 start.x=x;
 start.y=y;
 vis[x][y][d]=1;
 start.step=0;
 start.left=d;
 queue<node>q;
 q.push(start);
 while(!q.empty())
 {
     node now;
     now =q.front();
     q.pop();
     //cnt[now.x][now.y]=now.step;
     if(now.x==m-1&&now.y==n-1)
     {
       return now.step;    
    }
    for(int t=0;t<4;t++)
    {
        node next;
         next.x=now.x+dir[t][0];
         next.y=now.y+dir[t][1];
         next.step=now.step+1;
         next.left=now.left;
         if(check(next.x,next.y)&&vis[next.x][next.y][next.left]==0&&Map[next.x][next.y]=='P')
         {
             vis[next.x][next.y][next.left]=1;
             q.push(next);
         }
    }
    for(int t=2;t<=d;t++)
    {
         node next;
         next.x=now.x+0;
         next.y=now.y+t;
         next.step=now.step+1;
         next.left=now.left-t;
         if(check(next.x,next.y)&&vis[next.x][next.y][next.left]==0&&Map[next.x][next.y]=='P'&&next.left>=0)
         {
             vis[next.x][next.y][next.left]=1;
             q.push(next);
         }
         next.x=now.x+t;
         next.y=now.y+0;
         next.step=now.step+1;
         next.left=now.left-t;
         if(check(next.x,next.y)&&vis[next.x][next.y][next.left]==0&&Map[next.x][next.y]=='P'&&next.left>=0)
         {
             vis[next.x][next.y][next.left]=1;
             q.push(next);
         }
         next.x=now.x+0;
         next.y=now.y-t;
         next.step=now.step+1;
         next.left=now.left-t;
         if(check(next.x,next.y)&&vis[next.x][next.y][next.left]==0&&Map[next.x][next.y]=='P'&&next.left>=0)
         {
             vis[next.x][next.y][next.left]=1;
             q.push(next);
         }
         next.x=now.x-t;
         next.y=now.y+0;
         next.step=now.step+1;
         next.left=now.left-t;
         if(check(next.x,next.y)&&vis[next.x][next.y][next.left]==0&&Map[next.x][next.y]=='P'&&next.left>=0)
         {
             vis[next.x][next.y][next.left]=1;
             q.push(next);
         }
    }
 }    
 return 0;
}
int main()
{
   cin>>m>>n>>d;
       memset(vis,0,sizeof(vis));
   for(int t=0;t<m;t++)
   {
       scanf("%s",Map[t]);
   }
   int ans=BFS(0,0);
   if(!ans)
   {
       cout<<"impossible"<<endl;
       return 0;
   }
   cout<<ans<<endl;
   return 0;
}

 

转载于:https://www.cnblogs.com/Staceyacm/p/11126324.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值