【状压+搜索】2019南邮wishare A题 快乐肥宅水

题意:给你个n*m的方阵,放了空瓶子的不能走,每次可以从一个地方向上下左右走不超过k步,问从起点到终点的最小步数

思考:每一个格点都可以向4个方向走1~k步,普通的bfs中从一个方向来了走到nx,ny之后,nx和ny就不能再被经过了。但是在本题中,可能我从上方走到nx,ny是到nx,ny最短的,但是我还能从左方走经过nx,ny到别的地方使别的地方花费时间最短。因此将一个点只能经过一次,改成一个点从每个方向只能经过一次,不过第一次访问到nx,ny时还是到这个点的最短花费。

#include<bits/stdc++.h>
using namespace std;
const int M=1010;
string s[M];
int d[M][M];
int vis[M][M];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m,k;
int x1,x2,t1,t2;
struct node
{
    int x,y;
    node(){};
    node(int x,int y):x(x),y(y){}
};
int solve()
{
     queue<node> q;
     memset(d,-1,sizeof(d));
     d[x1][t1]=0;
     q.push(node(x1,t1));
     vis[x1][t1]=(1<<4)-1;          //四个方向都不可以再过来了
     while(!q.empty())
     {
         node tmp=q.front();
         q.pop();
         int x=tmp.x,y=tmp.y;
         if(x==x2&&y==t2) return d[x2][t2];
         for(int i=0;i<4;++i)
         {
             for(int j=1;j<=k;++j)
             {
                 int nx=x+j*dx[i],ny=y+j*dy[i];
                 if(nx>0&&nx<n&&ny>0&&ny<m&&s[nx][ny]!='#'&&!(vis[nx][ny]&(1<<i)))  //没有从i方向来过
                 {
                     if(d[nx][ny]==-1)
                     {
                         d[nx][ny]=d[x][y]+1;
                         q.push(node(nx,ny));
                     }

                 }
                 vis[nx][ny]|=1<<i;         //这个方向来过
             }

         }
     }
}
int main()
{
    for(int i=0;i<n;++i)
        cin>>s[i];

    cin>>x1>>t1>>x2>>t2;
    int ans=solve();
    cout<<ans<<endl;




}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值