入门深搜(递归)

所谓无底深渊,下去,也是前程万里

入门深搜,以 hdu1241为例进行讲解!
题目的意思大概是有一块油田,要你求有多少个不同的石油储藏(如果每个油袋是上下左右,对角相邻的,那么说这是一个石油储藏,*代表没有油袋,@代表有油袋)
典型的深搜算法。我们从找到的第一个油袋@开始,上下左右,对角进行搜索,找到一个油袋就用把当前油袋变为 *,直到图中没有@了为止!那么我们总共进行了多少次深搜就有多少个石油储藏!
代码如下:

#include <algorithm>
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

const int MAX_M = 101;
const int MAX_N = 101;  //最大油田面积
char ch[MAX_M][MAX_N];  //油田
int m, n;               //油田大小

void dfs(int, int);

int main() {
  while (cin >> m >> n) {
    if (m == 0 && n == 0) break;
    for (int i = 0; i < m; i++) {
      cin >> ch[i];
    }
    //输入!
    int cnt = 0;
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        //从有油袋的地方开始
        if (ch[i][j] == '@') {
          dfs(i, j);
          cnt++;
        }
      }
    }
    cout << cnt << endl;
  }
  return 0;
}

//现在的位置为(x,y)
void dfs(int x, int y) {
  //将当前位置替换为*
  ch[x][y] = '*';
  for (int nx = -1; nx <= 1; ++nx) {
    for (int ny = -1; ny <= 1; ++ny) {
      //往x方向移动nx,y方向移动nx,此时的位置为(dx,dy)
      int dx = nx + x, dy = ny + y;
      //判断(dx,dy)是否在油田内,是否是油袋!
      if (0 <= dx && dx < m && 0 <= dy && dy < n && ch[dx][dy] == '@') {
        dfs(dx, dy);
      }
    }
  }
  return;
}

牛刀小试
代码如下:

#include <algorithm>
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

const int MAX_W = 22;
const int MAX_H = 22;   //最大长方形
int w, h;               //长方形宽长
int cnt;                //满足条件的.的个数
char ch[MAX_W][MAX_H];  //长方形

void dfs(int x, int y);

int main() {
  while (cin >> w >> h) {
    if (w == 0 && h == 0) break;
    for (int i = 0; i < h; i++) {
      cin >> ch[i];
    }
    cnt = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        //从@开始
        if (ch[i][j] == '@') {
          dfs(i, j);
        }
      }
    }
    cout << cnt << endl;
  }
  return 0;
}

void dfs(int x, int y) {
  //每调用一次,cnt就加一,因为是找满足条件的.的个数
  cnt++;
  //标记
  ch[x][y] = '#';
  for (int nx = -1; nx <= 1; ++nx) {
    for (int ny = -1; ny <= 1; ++ny) {
      if (nx == ny || nx == -ny) {
        continue;
      }
      //题目要求只能上下左右移动,对角相邻没用!
      int mx = x + nx;
      int my = y + ny;
      //判断是否在长方形内,是否是.
      if (0 <= mx && mx < h && 0 <= my && my < w && ch[mx][my] == '.') {
        dfs(mx, my);
      }
    }
  }
  return;
}

才疏学浅,望雅正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值