给定一个 nn 行 mm 列的方格矩阵。行坐标从上到下为 1∼n1∼n,列坐标从左到右为 1∼m1∼m。
其中的每个方格,要么是空格(用 .
表示),要么包含障碍物(用 *
表示)。
初始时,一个人位于第 rr 行第 cc 列的空格之中。
他可以沿上下左右四个方向进行移动,每次移动一格距离。
对于他的移动,有如下限制:
- 他不能进入到包含障碍物的方格中,也不能走出矩阵的边界。
- 在整个移动过程中,他向左移动的总次数不能超过 xx 次。
- 在整个移动过程中,他向右移动的总次数不能超过 yy 次。
请问,一共有多少个空格是此人可以抵达的?
注意,初始空格视为此人可达。
输入格式
第一行包含两个整数 n,mn,m。
第二行包含两个整数 r,cr,c。
第三行包含两个整数 x,yx,y。
接下来 nn 行,每行包含一个长度为 mm 的由 .
和 *
组成的字符串,用来描述方格矩阵。
输入保证第 rr 行第 cc 列的方格一定是空格。
输出格式
一个整数,表示可达空格数量。
01bfs使用场景:当权重有0和1时,此时普通bfs无法求解,其核心是使用双端队列deque来代替普通队列,若权重为0,则向队头插入,为1向队尾插入。
代码:
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> pii;
const int N=2e3+10;
char g[N][N];
int n,m,sx,sy,l,r;
int dis[N][N];//dis[i][j]代表走到i,j这点,向右最少走几步
bool st[N][N];
void bfs()
{
memset(dis,0x3f,sizeof dis);
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
deque<pii> q;
q.push_front({sx,sy});
dis[sx][sy]=0;
while(q.size())
{//双端队列bfs本质是dijkstra,因此在出队时要判重
auto t=q.front();q.pop_front();
if(st[t.x][t.y]) continue;
st[t.x][t.y]=1;
for(int i=0;i<4;i++){
int a=t.x+dx[i],b=t.y+dy[i];
if(a<0||a>=n||b<0||b>=m||g[a][b]=='*') continue;
int w=0;
if(i==1) w=1;
if(dis[t.x][t.y]+w<dis[a][b]){
dis[a][b]=dis[t.x][t.y]+w;
if(w) q.push_back({a,b});
else q.push_front({a,b});
}
}
}
}
signed main()
{
cin>>n>>m>>sx>>sy>>l>>r;
for(int i=0;i<n;i++) cin>>g[i];
sx--;sy--;
bfs();
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){//向右为dis,则dis-向左=j-sy,因此向左步数满足<=l即可
if(dis[i][j]<=r&&(dis[i][j]-(j-sy))<=l) ans++;
}
cout<<ans<<endl;
return 0;
}