Labyrinth CodeForces - 1063B (BFS 标特殊记)

题意:一张n*m得网格图,有障碍物,起点是(r,c),每步能向上、下、左、右中的某个方向走一格,向左走不能超过x步,向右走不能超过y步,问从起点可以到达格数?

思路:设一个tag类型的vis[][]标记,tag的结构体里有l、r两个属性,走到 (x,y) 这一格时,vis[x][y].l 表示已经向左走了多少步,vis[x][y].r 表示已经向右走了多少步,如果l r都是-1,表示这格还没访问过。

在满足边界条件、障碍条件的情况下,只有当 (该网格从未被访问过 或 向左走的步数大于此时向左走的步数 或 向右走的步数大于此时向右走的步数) 且 向左向右的步数限制都还在x、y内,才将该点入队访问。

看代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,r,c,x,y;
char s[2005][2005];
int dir[][4]={{0,1},{0,-1},{1,0},{-1,0}};
struct Node{
    int x,y;
    int l,r;
};

struct tag{
    int l,r;
    tag(){l=r=-1;}
}vis[2005][2005];

int bfs(){
    int ans=0;
    queue<Node>q;
    Node v;
    v.x=r,v.y=c,v.l=0,v.r=0;
    q.push(v);
    ++ans;
    vis[r][c].l=0,vis[r][c].r=0;
    while(!q.empty()){
        auto t=q.front();
        q.pop();
        
        for(int i=0;i<4;++i){
            Node nt;
            //cout<<i<<": ";
            nt.x=t.x+dir[i][0], nt.y=t.y+dir[i][1];
            nt.l=t.l,nt.r=t.r;
            //cout<<dir[i][0]<<" "<<dir[i][1]<<" ---  ";

            if( s[nt.x][nt.y]=='.' && 0<nt.x && nt.x<=n && 0<nt.y && nt.y<=m ) {
                if(i==0) ++nt.r;
                if(i==1) ++nt.l;

                //nt.l = t.l + dir[i][1]==-1?1:0, nt.r = t.r + dir[i][1]==1?1:0;
                //cout<<t.x<<" "<<t.y<<" "<<nt.x<<" "<<nt.y<<" "<<nt.l<<" "<<nt.r<<endl;
                if((vis[nt.x][nt.y].l==-1||vis[nt.x][nt.y].l>nt.l||vis[nt.x][nt.y].r>nt.r) && nt.l<=x && nt.r<=y ){

                    if(vis[nt.x][nt.y].l==-1){
                        ++ans;
                        //cout<<t.x<<" "<<t.y<<" "<<nt.x<<" "<<nt.y<<" "<<nt.l<<" "<<nt.r<<endl;
                    } 
                    vis[nt.x][nt.y].l=nt.l;
                    vis[nt.x][nt.y].r=nt.r;
                    q.push(nt);
                }
            }

        }
        
    }
    return ans;
}

int main(){
    scanf("%d%d%d%d%d%d",&n,&m,&r,&c,&x,&y);
    for(int i=1;i<=n;++i){
        scanf("%s",s[i]+1);
    }
    printf("%d",bfs());
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值