深度优先搜索 dfs Oil Deposits HDU - 1241

它从某个状态开始,不断转移状态直到无法转移;然后退回到前一步的状态,继续转移到其他状态,如此不断重复,直到找到最终的解。例如求解数独,首先在某个格子填入适当的数字,然后再继续在下一个格子内填入数字,如此继续下去。如果发现某个格子无解了,就放弃前一个格子上选择的数字。改用其他可行的数字。根据深度优先搜索的特点,采用递归函数实现比较简单。

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid. 
InputThe input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket. 
OutputFor each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets. 
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0 
Sample Output
0
1
2
2

题意:看八个方位上是否有连续的'@'符号,表示连在一起的油田;从任意‘@’开始,不停的把邻接的部分用‘*’代替,1次dfs后与初始的这个‘@’连接的所有‘@’被替换成了‘*’,直到图中不再有‘@’为止,总共进行dfs的次数进行计数,便是油田的个数,由于题意要求,每块油田不能超过100个‘@’,当到100个‘@’后,重新再次dfs搜索;8个方向对应了8种状态转移;每个格子作为dfs的参数至多被调用一次,所以复杂度为o(8*n*m).


ac代码:

#include<stdio.h>

char a[150][150]; 
int n,m;

void dfs(int x,int y){
    //将现在所在位置替换成*
    a[x][y] = '*';
    //循环遍历移动的8个方向,把相邻的位置上的‘@’替换成为‘*'; 
    for(int dx = -1;dx <= 1;dx++){
        for(int dy = -1;dy <= 1;dy++){
            //向x方向移动dx,向y方向移动dy,移动结果为(nx,ny)
            int nx = x + dx,ny = y + dy;
            if(nx >= 0 && nx < n && ny >= 0 && ny < m && a[nx][ny] == '@')  //判断8个相邻位置上是否是油田; 
                dfs(nx,ny);//进行深度搜索; 
        }
    }
    return ;
}

int main(){
    while(scanf("%d %d",&n,&m)!=EOF && n != 0 && m != 0){
        int sum = 0;//记录dfs的搜索次数,即为油田的个数; 
        getchar();//消去换行符; 
        for(int i = 0;i < n;i++){
                scanf("%s",a[i]);//录入在该矩阵上的油田分布; 
            getchar();
        }

        for(int i = 0;i < n;i++){
            for(int j = 0;j < m;j++){
                if(a[i][j] == '@'){  //判断该位置上是否有油田; 
                    sum++;
                    dfs(i,j); //进行深度搜索; 调用子函数; 
                }
            }
        }

        printf("%d\n",sum);
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值