牛客寒假算法基础集训营6 J-迷宫
链接:https://ac.nowcoder.com/acm/contest/332/J
来源:牛客网
题目描述
你在一个 n 行 m 列的网格迷宫中,迷宫的每一格要么为空,要么有一个障碍。
你当前在第 r 行第 c 列(保证该格子为空)。每次移动你可以向上下左右任意一个方向移动一格,前提是不能走到障碍上,也不能超出迷宫的边界。
你向左移动的次数不能超过 x 次,向右不能超过 y 次。
问在这种情况下,对于每个格子,是否存在一种移动方案让你走到它。
输出有多少个格子存在移动方案让你走到它。
输入描述:
第一行两个正整数 n,m 。
第二行两个正整数 r,c ,保证1≤r≤n ,1≤c≤m 。
第三行两个整数 x,y ,保证 0≤x,y≤109 。
接下来 n 行,每行一个长度为 m 的字符串,
第 i 行第 j 个字符表示迷宫第 i 行第 j 列的格子,
字符为.
表示格子为空,字符为*
表示格子上有一个障碍。
输出描述:
输出一个数,表示有多少个格子存在移动方案让你走到它。
示例1
输入
4 5
3 2
1 2
.....
.***.
...**
*....
输出
10
说明
将能走到的格子用+标记:
+++..
+***.
+++**
*+++.
示例2
输入
4 4
2 2
0 1
....
..*.
....
....
输出
7
说明
将能走到的格子用+标记:
.++.
.+*.
.++.
.++.
备注:
对于全部数据,1≤n,m≤1000 。
思路
单纯的BFS模板题,理解BFS的原理直接写就行,注意坑点 向左向右移动的总次数的限制,所以每次都要保存左边右两边还剩多少的移动次数。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
char Map[maxn][maxn];
int vis[maxn][maxn];
int n,m,r,c,x,y;
int ans=0;
int go[4][2]={1,0,0,1,-1,0,0,-1};
struct Node{
int x,y;
int l,r;
};
bool judge(Node i){
if(i.x>=0 && i.y>=0 && i.x<n && i.y<m && Map[i.x][i.y]=='.' && !vis[i.x][i.y])
return true;
else return false;
}
void P(Node i){
printf("%d %d %d %d\n",i.x+1,i.y+1,i.l,i.r);
}
void BFS(){
queue<Node>q;
Node now,next;
now.x=r-1;
now.y=c-1;
now.l=x;
now.r=y;
vis[r-1][c-1]=1;
ans++;
q.push(now);
while(!q.empty()){
now=q.front();
//P(now);
q.pop();
for(int i=0; i<4; i++){
if(i==1&&now.r>0){
next.x=now.x+go[i][0];
next.y=now.y+go[i][1];
next.l=now.l;
next.r=now.r-1;
if(judge(next)){
vis[next.x][next.y]=1;
ans++;
q.push(next);
}
}
else if(i==3&&now.l>0){
next.x=now.x+go[i][0];
next.y=now.y+go[i][1];
next.l=now.l-1;
next.r=now.r;
if(judge(next)){
vis[next.x][next.y]=1;
ans++;
q.push(next);
}
}
else if(i==0 || i==2){
next.x=now.x+go[i][0];
next.y=now.y+go[i][1];
next.l=now.l;
next.r=now.r;
if(judge(next)){
vis[next.x][next.y]=1;
ans++;
q.push(next);
}
}
}
}
}
int main(){
scanf("%d %d %d %d %d %d",&n,&m,&r,&c,&x,&y);
getchar();
for(int i=0; i<n; i++)
scanf("%s",Map[i]);
BFS();
printf("%d\n",ans);
}