P1596 [USACO10OCT]Lake Counting S
P1596 [USACO10OCT]Lake Counting S
洛谷题
这是一道DFS ( Depth First Search 深度优先搜索) 的题目
啥是DFS?
DFS就是从起点开始搜索,当碰到岔道口时,总是选择一条路前进。知道无路可走,才返回到离自己最近的没被访问过的岔道口继续前进。
举个栗子:
我们有一棵树
我们从根节点A开始搜索,第一步走到B节点,发现可以继续走,便走到D节点,发现又可以继续走,就来到了H节点。
到了H节点之后,发现无路可走,便退回到D节点,向I节点方向走。直到H I J三个节点都被访问过,于是再退回到B节点开始向E节点方向搜索......
直到找到终点,搜索结束。
将此过程记录下来,如下:
A->B
B->D
D->H
D->I
D->J
B->E
......
C->F
C->G
我们将这一不撞南墙不回头过程叫做DFS(Depth First Search深度优先搜索),简称深搜。
现在来看题目:
题目要求我们找水坑的数量
对于每一个水坑,我们都可以用DFS来遍历一遍,并作为已访问。
DFS函数思路:
1 void dfs(int x,int y){
2 //将该坐标标记为已访问
3 //判断该点周围8个方向是否有水洼
4 //如果有继续搜索下一个点
5 }
如何判断该点周围8个方向是否有水洼呢?
这个时候我们就需要请我们的老朋友:方向数组来帮忙
方向数组就是用数组记录新坐标与当前坐标的关系的数组(如下图)
该题的方向数组长这样:
int dx[]={0,0,1,-1,-1,1,-1,1};
int dy[]={1,-1,0,0,1,1,-1,-1};
整个代码思路:
1 //头文件、宏定义
2 using namespace std;
3 //定义田地长宽、田地、方向数组、计数器
4 void dfs(int x,int y){
5 //将该坐标标记为已访问
6 //判断该点周围8个方向是否有水洼
7 //如果有继续搜索下一个点
8 }
9 int main(){
10 //初始化田地
11 //输入
12 //遍历整个田地
13 /*
14 如果当前坐标为水洼
15 计数器++
16 从当前点开始搜索 标记水洼
17 */
18 //输出
19 return 0;
20 }
理解思路后,便可以着手写代码:
AC Code:
1 #include<bits/stdc++.h>//万能头美滋滋
2 #define ll long long
3 using namespace std;
4 int n,m;
5 int cnt=0;
6 char g[122][122];
7 int dx[]={0,0,1,-1,-1,1,-1,1};//方向数组
8 int dy[]={1,-1,0,0,1,1,-1,-1};
9 void dfs(int x,int y){
10 g[x][y]='.';//将水洼标记为旱地后,不会被再次访问
11 for(int i=0;i<8;i++){
12 if(g[x+dx[i]][y+dy[i]]!='.') dfs(x+dx[i],y+dy[i]);
13 }
14 }
15 int main(){
16 cin>>n>>m;
17 memset(g,'.',sizeof g);//将田地初始化为'.'需要cstring头文件
18 for(int i=1;i<=n;i++){
19 for(int j=1;j<=m;j++){
20 char c;
21 cin>>c;
22 g[i][j]=c;
23 }
24 }
25 for(int i=1;i<=n;i++){
26 for(int j=1;j<=m;j++){
27 if(g[i][j]!='.'){//旱地不需要被搜索
28 cnt++;
29 dfs(i,j);
30 }
31 }
32 }
33 cout<<cnt;
34 return 0;
35 }
感谢浏览!
祝所有的母亲母亲节快乐!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律