先感谢一下远航大佬踩坑,广搜无限tl和wa还d不出来,用深搜就一遍过了。
先上题目(中文版吧)
链接:http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1004&cid=35803
口述题目环节
题意:输入行列数,输入一个地图,"@“代表有油,” * “没油。每个”@“的八个方向如果有”@"连着的话属于同一个油层。判断有多少个油层。
代码详解环节
1、全局部分
int m,n;
char map[120][120];
int fangxiang[8][2]= {{-1,-1},{-1,0},
{-1,1},{0,1},{0,-1},{1,1},{1,0},{1,-1}
};
先是m、n分别为行数和列数。
然后是用数组开大于100x100单位的地图。
然后是重点部分:定义方向数组,把方向记录在数组里(顺序为 1左上角 2上 3右上角 4右 5左 6右下角 7下 8左下角)。
2、主函数部分
part1
int main() {
int i,j;
while(~scanf("%d %d",&m,&n)) {
int sum=0;
if (m==0&&n==0) {
break;
}
sum用于记录油层数,别的没什么好说的。
part2
for(i=0; i<m; i++) {
scanf("%s",map[i]);
}
这个是一个新学的操作,用数组地址来给数组赋值,map[i]代表map数组第i行的地址,就可以一行一行的输入地图。要注意的是赋值是从第0个开始赋值的,所以这里也决定了地图的边缘要从0开始而不能是1。
part3
for(i=0; i<m; i++) {
for(j=0; j<n; j++) {
if(map[i][j]=='@') {
sum++;
dfs(i,j);
}
}
}
printf("%d\n",sum);
}
return 0;
}
先从地图左上角开始一个一个寻找油,找到第一个油以后,sum数量+1,然后就开始进入子函数深搜,最后输出答案。
3、深搜函数部分
part1
void dfs(int x,int y) {
int i;
map[x][y]='*';
主函数发现第一个油层后,传入坐标,先将发现的油层覆盖掉,避免重复。
part2
for(i=0; i<8; i++) {
int sex=x+fangxiang[i][0];
int sey=y+fangxiang[i][1];
if(sex<0||sex>=m||sey<0||sey>=n) {
continue;
}
if(map[sex][sey]=='@')
dfs(sex,sey);
}
循环8个方向的递归,体会到了数组存方向的奥妙。if判断越界然后continue,第二个if判断发现油然后传新坐标递归。
代码总览环节
#include<stdio.h>
int m,n;
char map[120][120];
int fangxiang[8][2]= {{-1,-1},{-1,0},
{-1,1},{0,1},{0,-1},{1,1},{1,0},{1,-1}
};
void dfs(int x,int y) {
int i;
map[x][y]='*';
for(i=0; i<8; i++) {
int sex=x+fangxiang[i][0];
int sey=y+fangxiang[i][1];
if(sex<0||sex>=m||sey<0||sey>=n) {
continue;
}
if(map[sex][sey]=='@')
dfs(sex,sey);
}
}
int main() {
int i,j;
while(~scanf("%d %d",&m,&n)) {
int sum=0;
if (m==0&&n==0) {
break;
}
for(i=0; i<m; i++) {
scanf("%s",map[i]);
}
for(i=0; i<m; i++) {
for(j=0; j<n; j++) {
if(map[i][j]=='@') {
sum++;
dfs(i,j);
}
}
}
printf("%d\n",sum);
}
return 0;
}
总结环节
这是学习了深广搜原理以后第一次写代码,心得的话主要是:
1:深搜的代码实现
2:用for和数组地址给二维数组赋值
3:用数组存方向的方法
吐槽一下在学校上课学深广搜的时候,师姐说:“这里要用xx函数,那里要用xx函数”全都是写函数,但是并没有具体讲函数怎么写。。。。真的是高估我了,看了别人的题解才学会具体代码怎么写。但是想一下,毕竟时间也有限嘛,不可能细讲。学了原理以后看别人的代码也能更好地知道别人每个步骤在干什么。
第三次写博客
2019.10.29