链接:https://ac.nowcoder.com/acm/contest/332/J
来源:牛客网
题目描述
你在一个 n 行 m 列的网格迷宫中,迷宫的每一格要么为空,要么有一个障碍。
你当前在第 r 行第 c 列(保证该格子为空)。每次移动你可以向上下左右任意一个方向移动一格,前提是不能走到障碍上,也不能超出迷宫的边界。
你向左移动的次数不能超过 x 次,向右不能超过 y 次。
问在这种情况下,对于每个格子,是否存在一种移动方案让你走到它。
输出有多少个格子存在移动方案让你走到它。
你当前在第 r 行第 c 列(保证该格子为空)。每次移动你可以向上下左右任意一个方向移动一格,前提是不能走到障碍上,也不能超出迷宫的边界。
你向左移动的次数不能超过 x 次,向右不能超过 y 次。
问在这种情况下,对于每个格子,是否存在一种移动方案让你走到它。
输出有多少个格子存在移动方案让你走到它。
输入描述:
第一行两个正整数 n,m 。
第二行两个正整数 r,c ,保证 1≤r≤n1≤r≤n ,1≤c≤m1≤c≤m 。
第三行两个整数 x,y ,保证 0≤x,y≤1090≤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≤10001≤n,m≤1000 。
#include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<string> #include<vector> #include<iostream> #include<cstring> #include<queue> #define inf 0x3f3f3f3f #define ll long long using namespace std; char a[1005][1005]; bool vis[1005][1005]; int d[4][2]={ {-1,0},{1,0},{0,-1},{0,1} };//上下左右 int n,m,sx,sy,leftt,rightt,ans;//不用left,right,cb编译报错,和内部函数名冲突 struct node { int x; int y; int l; int r; }; node s;//起点 queue<node>que; void bfs() { ans=0; while(!que.empty()) que.pop(); que.push(s); while(!que.empty()) { node now=que.front(); que.pop(); ans++; node then=now; for(int i=0;i<4;i++) { ///栽了好久,要重新定义一个变量then,如果用原来的now会对本身进行操作,造成错误 then.x=now.x+d[i][0]; then.y=now.y+d[i][1];//下一步的坐标 if( then.x<0 || then.x>=n || then.y<0 || then.y>=m || vis[then.x][then.y] || a[then.x][then.y]=='*' ) continue; ///越界 或者 访问过 或者 障碍 if(i==0 || i==1) //上下,随便走 { que.push( {then.x,then.y,now.l,now.r} ); vis[then.x][then.y]=true; } else if(i==2 && then.l < leftt)//左,需要判断步数,不能等于,表示还有一脚的机会踏出去 { then.l++; que.push( {then.x,then.y,now.l+1,now.r} ); vis[then.x][then.y]=true; } else if(i==3 && now.r < rightt)//右,需要判断步数 { then.r++; que.push( {then.x,then.y,now.l,now.r+1} ); vis[then.x][then.y]=true; } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(vis,false,sizeof(vis)); scanf("%d%d",&sx,&sy);//起点横纵坐标 s.x=sx-1; s.y=sy-1; s.l=0; s.r=0; scanf("%d%d",&leftt,&rightt); getchar(); vis[sx-1][sy-1]=true; for(int i=0;i<n;i++) scanf("%s",a[i]); bfs(); printf("%d\n",ans); } return 0; }