Oil Deposits 挖油题——深度优先搜索(deep first search)

先感谢一下远航大佬踩坑,广搜无限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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值