深度优先搜索的用法——lake counting

深度优先搜索的用法——lake counting

问题主题:Lake Counting

问题描述:

有一个大小为N*M的园子,雨后积了很多水。八连通的积水被认为是在一起的。请求出园子里共有多少个水洼?(八连通是指下图中相对+*部分)

+++

+*+

+++

限制条件:

N,M <= 100

样例:

输入

N=10, M=12

园子如下图(‘+’表示积水,’*’表示没有积水)

+********++*

*+++*****+++

****++***++*

*********++*

*********+**

**+******+**

*+*+*****++*

+*+*+*****+*

*+*+******+*

**+*******+*

输出

3

 

 

【解法一】

解题分析:

    从任意的’+’开始,不停地把邻接的部分用’*’代替,一次dfs(深度优先遍历)遍历后,与初始的这个+所连接的所有+都会被替换成*,因此直到图中没有+为止,总共进行dfs的次数即为积水的次数。

程序实现:

 

C++

 

#include "iostream"

 

using namespace std;

 

const int N = 10;

const int M = 12;

 

char garden[N][M+1] = {

"+********++*",

"*+++*****+++",

"****++***++*",

"*********++*",

"*********+**",

"**+******+**",

"*+*+*****++*",

"+*+*+*****+*",

"*+*+******+*",

"**+*******+*"

};

 

void dfs(int x, int y);

 

void solve() {

int count = 0;

for(int j=0; j<N; j++) {

for(int i=0; i<M; i++){

if(garden[j][i] == '+') {

dfs(j, i);

count ++;

}

}

}

cout << count << endl;

}

 

void dfs(int y, int x) {

garden[y][x] = '*';

for(int dy=y-1; dy<=y+1; dy++) {

for(int dx=x-1; dx<=x+1; dx++) {

if(dx >=0 && dy >= 0 && dx < M && dy < N && garden[dy][dx] == '+') {

dfs(dy, dx);

}

}

}

}

 

int main() {

solve();

return 0;

}

 

Java

/**
 * User: luoweifu
 * Date: 14-1-7
 * Time: 下午4:53
 */
public class LakeCounting {
public static final int N = 10;
public static final int M = 12;
private String garden[] = {
"+********++*",
"*+++*****+++",
"****++***++*",
"*********++*",
"*********+**",
"**+******+**",
"*+*+*****++*",
"+*+*+*****+*",
"*+*+******+*",
"**+*******+*"
};
 
public void solve() {
int count = 0;
for(int j=0; j<N; j++) {
for(int i=0; i<M; i++){
if(garden[j].charAt(i) == '+') {
dfs(j, i);
count ++;
}
}
}
System.out.println(count);
}
 
public void dfs(int y, int x) {
StringBuilder stringY = new StringBuilder(garden[y]);
stringY.setCharAt(x, '*');
garden[y] = stringY.toString();
for(int dy=y-1; dy<=y+1; dy++) {
for(int dx=x-1; dx<=x+1; dx++) {
if(dx >=0 && dy >= 0 && dx < M && dy < N && garden[dy].charAt(dx) == '+') {
dfs(dy, dx);
}
}
}
}
 
public static void main(String args[]) {
LakeCounting lakeCounting = new LakeCounting();
lakeCounting.solve();
}
}

 

 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌尘(MoChen)

爱打赏的人技术成长更开哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值