输入一个n*n的黑白图像(1表示黑色,0表示白色),任务是统计其中八连块的个数。如果两个黑格子有公共边或者公共顶点,就说它们属于同一个八连块。如图6-11所示的图形有3个八连块。

图6-11  拥有3个八连块的黑白图形

【分析】

用递归求解:从每个黑格子出发,递归访问它所有的相邻黑格。

int mat[MAXN][MAXN], vis[MAXN][MAXN];
void dfs(int x, int y) {
if(!mat[x][y] || vis[x][y]) return; // 曾经访问过这个格子,或者当前格子是白色
vis[x][y] = 1; // 标记(x,y)已访问过
dfs(x-1,y-1); dfs(x-1,y); dfs(x-1,y+1);
dfs(x-1,y); dfs(x,y+1);
dfs(x+1,y-1); dfs(x+1,y); dfs(x+1,y+1); // 递归访问周围的八个格子
}
这里,黑格(x,y)的mat[x][y]为1,白格为0。为了避免同一个格子访问多次,用标志vis[x][y]记录格子(x,y)是否访问过。在输入之前,在迷宫的外面加上一圈虚拟的白格子,见下面的程序。
memset(mat, 0, sizeof(mat)); //所有格子都初始化为白色,包括周围一圈的虚拟格子
memset(vis, 0, sizeof(vis)); // 所有格子都没有访问过
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%s", s);
for(int j = 0; j < n; j++)
mat[i+1][j+1] = s[j]-'0'; // 把图像往中间移动一点,空出一圈白格子
}

接下来,只需不断找黑格,然后调用dfs。从它出发寻找八连块:

int count = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(!vis[i][j] && mat[i][j]) { count++; dfs(i,j); }
//找到没有访问过的黑格
printf("%d\n", count);

完整的程序如下:

#include <stdio.h>
#include <string.h>
const int MAXN = 1000;
int n; int mat[MAXN][MAXN], vis[MAXN][MAXN];
void dfs(int x, int y) { if(!mat[x][y] || vis[x][y]) return; //曾经访问过这个格子,或者当前
格子是白色
vis[x][y] = 1; // 标记(x,y)已访问过
dfs(x-1,y-1); dfs(x-1,y); dfs(x-1,y+1);
dfs(x-1,y); dfs(x,y+1);
dfs(x+1,y-1); dfs(x+1,y); dfs(x+1,y+1); // 递归访问周围的八个格子
} int main() {
char s[MAXN + 10];
memset(mat, 0, sizeof(mat)); // 所有格子都初始化为白色,包括周围
一圈的虚拟格子
memset(vis, 0, sizeof(vis)); // 所有格子都没有访问过
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%s", s);
for(int j = 0; j < n; j++)
mat[i+1][j+1] = s[j]-'0'; // 把图像往中间移动一点,空出一圈白格子
}
int count = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
// 找到没有访问过的黑格
if(!vis[i][j] && mat[i][j]) { count++; dfs(i,j); }
printf("%d\n", count);
return 0;
}

上面的函数dfs就是深度优先遍历(Depth-FirstSearch,DFS)的算法,DFS和BFS一样,都是从一个结点出发,按照某种特定的次序访问图中的其他特点。不同的是,BFS使用队列来存放待扩展结点,而DFS使用的是栈。

附:我自己理解后敲的代码:

#include <stdio.h>
#include <string.h>
#include<algorithm>
#include<iostream>
#define M 1020
using namespace std;
int n;
int i,j;
char map[M][M];
void dfs(int x,int y)
{ if(map[x][y]!='1'||x<0||y<0||x>=n||y>=n)
return; //曾经访问过这个格子,或者当前格子是白色
else
{
map[x][y] = '0'; // 标记(x,y)已访问过
dfs(x-1,y-1);
dfs(x-1,y+1);
dfs(x-1,y);
dfs(x,y+1);
dfs(x,y-1);
dfs(x+1,y-1);
dfs(x+1,y);
dfs(x+1,y+1); // 递归访问周围的八个格子
}
} int main()
{
memset(map, 0, sizeof(map)); // 所有格子都没有访问过
scanf("%d", &n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
cin>>map[i][j]; int count = 0;
for(i = 0; i <n; i++)
for(j = 0; j <n; j++)
{
// 找到没有访问过的黑格
if(map[i][j]=='1')
{
dfs(i,j);
count++;
}
}
printf("%d\n", count);
return 0;
}
/*
6
100100
001010
000000
110000
111000
010100
*/

黑白图像(DFS)的更多相关文章

  1. dfs入门-cogs1640[黑白图像]

    题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=vxSmxkeqa [题目描述] 输入一个n×n的黑白图像(1表示黑色,0表示白色),任务 ...

  2. 小白书 黑白图像【DFS/Flood Fill】

    http://blog.csdn.net/u010470972/article/details/33415617 Description 输入一个n×n的黑白图像(1表示黑色,0表示白色),任务是统计 ...

  3. [ActionScript 3.0] AS3.0 将图像的Alpha通道转换为黑白图像(分离ARGB方式)

    import flash.display.BitmapData; import flash.display.Bitmap; /** * 将图像的Alpha通道转换为黑白图像(分离ARGB方式) */ ...

  4. [ActionScript 3.0] AS3.0将图像的Alpha通道转换为黑白图像(复制通道方式)

    import flash.display.BitmapData; /** * 将图像的Alpha通道转换为黑白图像 */ var p:Point = new Point(0,0); var bmpd: ...

  5. TZOJ 3533 黑白图像(广搜)

    描述 输入一个n*n的黑白图像(1表示黑色,0表示白色),任务是统计其中八连块的个数.如果两个黑格子有公共边或者公共顶点,就说它们属于同一个八连块.如图所示的图形有3个八连块. 输入 第1行输入一个正 ...

  6. MATLAB读取黑白图像显示却是黑色,24位深转8位深黑白图像解决方法

    1.24位深转8位深: ps将24位深原图.png保存为GIF图256即为8位,再将8位gif图转为需要的.png,即转为8位深png图. 2.MATLAB读取黑白图像显示几乎全为黑色: 这是最近处理 ...

  7. uoj #139. 【UER #4】被删除的黑白树 dfs序 贪心

    #139. [UER #4]被删除的黑白树 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/139 Descript ...

  8. uva806 Spatial Structures 空间结构 (黑白图像的四分树表示)

    input 8 00000000 00000000 00001111 00001111 00011111 00111111 00111100 00111000 -8 9 14 17 22 23 44 ...

  9. Visio中如何绘制黑白图像

随机推荐

  1. .getBoundingClientRect()

    .getBoundingClientRect() 该方法获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置,他返回的是一个对象,即Object,该对象有4个属性:top,left,right, ...

  2. Bootstrap_Javascript_弹出框

    HTML: <button type="button" class="btn btn-default" data-container="body ...

  3. memcache 操作类

    <?php /** * memcache 操作实现 * @author timeless */ class Memcache_manage { //CI原始的信息 private $_ci; p ...

  4. nginx 一般配置实例 静态页面

    # 使用的用户和组 user www www; # 指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍,例如两个四核CPU,则总核数为8) worker_processes 8; # 指定错误日 ...

  5. 求助:对话框下OnInitDialog中使用SetTimer无效

    原文地址:http://www.w3c.com.cn/%E6%B1%82%E5%8A%A9%EF%BC%9A%E5%AF%B9%E8%AF%9D%E6%A1%86%E4%B8%8Boninitdial ...

  6. ORACLE 日志 logminer 使用

    1. logminer安装 SQL> @$ORACLE_HOME/rdbms/admin/dbmslm.sql Package created. Grant succeeded. Synonym ...

  7. BZOJ 3240 矩阵游戏

    Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的\(n\)行\(m\)列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用\(F[i][j]\)来 ...

  8. WSS存储服务器(Windows Storage Server) 2012新功能解析

    虽然最近一段时间有关微软的新闻大多数集中在Windows 8以及Surface平板设备身上,但数周之前Windows Server 2012新版本中所包含的Windows Storage Server ...

  9. 《how to design programs》15章 相互引用的数据定义

    由结构体组成的表与结构体中的表. 在用追溯形式建立家家谱树时,我们通常从某个后代除法,依次处理它的父母,组父母等.而构建树时,我们会不断添加谁是谁的孩子,而不是写出谁是谁的父母,从而建立一颗后代家谱树 ...

  10. 【HDOJ】2531 Catch him

    简单BFS.就是要把所有的D点当成一个整体考虑(整体移动). /* 2531 */ #include <iostream> #include <queue> #include ...