给定一个 n 行 m 列的方格矩阵。行坐标从上到下为 1∼n,列坐标从左到右为 1∼m。
其中的每个方格,要么是空格(用 .
表示),要么包含障碍物(用 *
表示)。
初始时,一个人位于第 r 行第 c 列的空格之中。
他可以沿上下左右四个方向进行移动,每次移动一格距离。
对于他的移动,有如下限制:
- 他不能进入到包含障碍物的方格中,也不能走出矩阵的边界。
- 在整个移动过程中,他向左移动的总次数不能超过 x 次。
- 在整个移动过程中,他向右移动的总次数不能超过 y 次。
请问,一共有多少个空格是此人可以抵达的?
注意,初始空格视为此人可达。
输入格式
第一行包含两个整数 n,m。
第二行包含两个整数 r,c。
第三行包含两个整数 x,y。
接下来 n 行,每行包含一个长度为 m 的由 .
和 *
组成的字符串,用来描述方格矩阵。
输入保证第 r 行第 c 列的方格一定是空格。
输出格式
一个整数,表示可达空格数量。
数据范围
前三个测试点满足 1≤n,m≤5。
所有测试点满足 1≤n,m≤2000,1≤r≤n,1≤c≤m,0≤x,y≤109。
输入样例1:
4 5
3 2
1 2
.....
.***.
...**
*....
输出样例1:
10
输入样例2:
4 4
2 2
0 1
....
..*.
....
....
输出样例2:
7
分析:本来写的dfs,结果爆栈了,换成了bfs结果运行时间过长,然后把queue换成deque就过了,上下走的从前面进队列,左右走的从后面进队列,如果一个点之前遍历过,且本次到达该点时剩余的想左和向右的步数都没原来遍历过的多,则可以不用遍历。an【】数组就是存储该点之前遍历过的步数情况
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=2e3+10;
int st[N][N];
char g[N][N];
int n,m,r,c,x,y,ans;
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
int cnt;
struct node{
int x,y;
};
struct node1{
int x,y,a,b;
};
vector<node>an[N*N];
void bfs()
{
deque<node1>q;
q.push_back({r,c,x,y});
while(q.size())
{
node1 u=q.front();
q.pop_front();
if(u.a<0||u.b<0)continue;
if(!st[u.x][u.y])
{
ans++;
st[u.x][u.y]=++cnt;
an[cnt].push_back({u.a,u.b});
}
else
{
int tem=st[u.x][u.y],flag=0;
for(int i=0;i<an[tem].size();i++)
{
if(u.a<=an[tem][i].x&&u.b<=an[tem][i].y)
{
flag=1;break;
}
}
if(flag)continue;
an[tem].push_back({u.a,u.b});
}
for(int i=0;i<4;i++)
{
int xx=u.x+dx[i],yy=u.y+dy[i];
if(xx<1||xx>n||yy<1||yy>m)continue;
if(g[xx][yy]=='*')continue;
if(i==2) q.push_back({xx,yy,u.a-1,u.b});
else if(i==3)q.push_back({xx,yy,u.a,u.b-1});
else q.push_front({xx,yy,u.a,u.b});
}
}
}
int main()
{
cin>>n>>m>>r>>c>>x>>y;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>g[i][j];
}
}
//dfs(r,c,x,y);
bfs();
cout<<ans;
return 0;
}
dfs的代码也附上去:
#include <bits/stdc++.h>
using namespace std;
const int N=2e3+10;
int st[N][N];
char g[N][N];
int n,m,r,c,x,y,ans;
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
int cnt;
struct node{
int x,y;
};
vector<node>an[N*N];
void dfs(int x1,int y1,int xnum,int ynum)
{
if(xnum<0||ynum<0) return;
if(!st[x1][y1])
{
ans++;
st[x1][y1]=++cnt;
an[cnt].push_back({xnum,ynum});
}
else
{
int tem=st[x1][y1];
for(int i=0;i<an[tem].size();i++)
{
if(xnum<=an[tem][i].x&&ynum<=an[tem][i].y)return;
}
an[tem].push_back({xnum,ynum});
}
for(int i=0;i<4;i++)
{
int xx=x1+dx[i],yy=y1+dy[i];
if(xx<1||xx>n||yy<1||yy>m)continue;
if(g[xx][yy]=='*')continue;
if(i==2) dfs(xx,yy,xnum-1,ynum);
else if(i==3)dfs(xx,yy,xnum,ynum-1);
else dfs(xx,yy,xnum,ynum);
}
}
int main()
{
cin>>n>>m>>r>>c>>x>>y;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>g[i][j];
}
}
dfs(r,c,x,y);
cout<<ans;
return 0;
}