[USACO10OCT]Lake Counting S - 洛谷
解题思路:
(1)读完题目,不难理解,每个水坑的八个方向如果还有水坑,那么是可以连在一块的,所以视为一个水坑,那么找到一个水坑的时候就要去看看他八个方向有没有水坑(DFS)
(2)创建a数组为地图,输入地图,然后开始遍历每一个点,如果是水坑的话,执行dfs(int x,int y)函数,传入此点的行列号,然后要去该点的八个方向,所以设置行列号的偏移方向数组
(3)首先dfs函数第一步,就是要将该点的水坑设置为旱地(想想为什么?)然后开始从他的八个方向开始搜索,如果在没有越界的情况下,有点是水坑,继续搜索
(4)那么dfs函数有没有出口呢?将该点所有连接的水坑变为旱地,即为出口,也就是所有的for循环执行完毕,执行完,此时也就产生了一个水坑,只是为了下次不再遍历,所以都设置成旱地
#include<bits/stdc++.h>
using namespace std;
int n,m,ans;
char a[110][110];//表示地图
int dx[10]={-1,1,0,0,-1,1,-1,1};//表示行的方向数组
int dy[10]={0,0,-1,1,-1,-1,1,1}; //表示列的方向数组
void dfs(int x,int y)//传入此时水坑的位置
{
a[x][y]='.';//将此时的水坑标注为旱地
for(int i=0;i<=7;i++)//依次去该水坑的八个方向搜索
{
int xx=x+dx[i];
int yy=y+dy[i];//形成新的坐标
if(xx>n||xx<1||yy>m||yy<1)//判断是否越界
continue;
if(a[xx][yy]=='W')//如果该点是水坑
dfs(xx,yy);//继续深搜
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>a[i][j];
}//输入地图
for(int i=1;i<=n;i++)//依次遍历每一个点
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='W')//如果这里是水坑的话
{
dfs(i,j);//开始深搜
ans++;//将所有可能连上的水坑都变为旱地,此时出现了一个水坑
}
}
}
cout<<ans;
return 0;
}
本文介绍了解决USACO10OCT LakeCounting问题的解题思路,通过深度优先搜索(DFS)找出地图上相连的水坑,并利用数组记录和标记,展示了如何利用八方向遍历和出口条件来计算连通水坑的数量。
308

被折叠的 条评论
为什么被折叠?



