华为OD真题-2023C-聚餐地点(BFS或者DFS)

https://oj.algomooc.com/problem.php?id=3515
题目描述
小华和小为是很好的朋友,他们约定周末一起吃饭,通过手机交流,他们在地图上选择了很多聚餐地点 (由于自然地形等原因,部分聚餐地点不可达),求小华和小为都能达到的聚餐地点有多少个。

输入描述
第一行输入\(m\)\(n\),\(m\)表示地图长度,\(n\) 表示地图宽度

第二行开始具体输入地图信息,地图信息包括

0 为通畅的道路
1 为障碍物(且仅 1 为障碍物)
2 为小华或小为,地图中必定有且仅有两个(非障碍物)
3 为被选中的聚餐地点(非障碍物)

输出描述
可以两方都到达的聚餐地点的数量,行末无空格

补充说明
地图长宽为\(m\)\(n\),\(4 <= m <= 100\)\(4 <= n <= 100\)

聚餐的地点数量为k,则\(1 < k <= 100\)

示例

输入
4 4
2 1 0 3
0 1 2 1
0 3 0 0
0 0 0 0
输出
2
备注
第一行输入地图的长宽为4和4
第二行开始为具体的地图,其中:
3 代表小华和小明的聚餐地点;
2 代表小华或小明(确保有2个);
0 代表可以通行的位置;
1 代表不可以出行的位置。
此时2者都能达到的聚餐位置有两处

本题的设问是需要寻找两个人同时可以到达的聚餐地点。

一种非常朴素的做法就是按照题目的要求进行模拟:先找到两个2的坐标位置,然后从这两个2出发进行DFS/BFS,分别记录能够到达的3的位置,再取交集,交集的长度就是答案。
但这种做法显得有些冗余,因为需要分别从两个起点出发进行两次搜索,并且还涉及到取交集的操作。

重新思考这个问题:由于题目中有且只有两个2,且地图中只有1是障碍物。若

  • 这两个2不处于同一个连通块中,那么小华和小为注定无法相遇,他们能够同时到达的3的个数一定是0
  • 这两个2处于同一个连通块中,那么小华和小为必然可以相遇,小华能够到达的3,小为也必定可以到达,反之亦然。因此小华能够到达的3的个数和小为能够到达的3的个数是一样的,也就是他们共同能够到达的聚餐地点。

因此,我们其实不需要分别从两个2出发做两次搜索。只需要从其中的某一个2出发做一次搜索即可:设置一个标记\(flag\)初始化为\(False\),表示能够遇到另一个2。如果搜索过程中遇到了另一个2,那么将flag设置为True.在搜索的过程中记录遇到的3的个数\(ans\)
退出搜索后,若
\(flag = False\),说明小华和小为无法相遇,可以同时到达的聚餐地点数量为0
\(flag = True\),说明小华和小为可以相遇,可以同时到达的聚餐地点数量为上述搜索中记录的3的个数ans
至于用DFS还是BFS,那都是套模板的事情了,非常简单。

BFS

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int n,m;
int flag=0;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int hx=-1,hy=-1,ans=0;
void bfs(int hx,int hy,vector<vector<int>> &a,vector<vector<int>> &vis){
	queue<pair<int,int>>q;
	q.push({hx,hy});
	while(!q.empty()){
		pair<int,int> z=q.front();
		int x=z.first;
		int y=z.second;
		if(a[x][y]==2){
			flag=1;
		}else if(a[x][y]==3){
			ans++;
		}
		q.pop();
		for(int i=0;i<4;i++){
			int xx=x+dx[i];
			int yy=y+dy[i];
			if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&a[xx][yy]!=1){
				vis[xx][yy]=1;
				q.push({xx,yy});
			}
		}
	}
}
int main(){
	cin>>n>>m;
	vector<vector<int>>a(n,vector<int>(m));
	vector<vector<int>>vis(n,vector<int>(m));
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>a[i][j];
			if(a[i][j]==2){
				hx=i,hy=j;
				
			}
		}
	}
	a[hx][hy]=0;
	bfs(hx,hy,a,vis);
	if(!flag){
		cout<<0<<"\n";
	}
	else{
		cout<<ans<<endl;
	}
}
posted @ 2024-04-20 21:47  lipu123  阅读(94)  评论(0)    收藏  举报