输入一个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. prototype/constructor/__proto__之constructor。

    1.constructor的字面意思就是构造.它是对象的一个属性,它对应的值是该对象的“构造者” //一.构造函数实例化的对象的constructor function Cmf(n,m){ this. ...

  2. 【开源】前端练手笔记,Chrome扩展应用程序(html+CSS+JS) (1)

    项目名称:github-notification 项目地址:https://github.com/WQTeam/github-notification 说明:本人打算抽时间学习前端(html + cs ...

  3. Python自动化运维之27、Django(一)

    一.概述 1.什么是框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单说就是使用别人搭好的舞台,你来做表演. 2.常 ...

  4. C语言知识总结

    明白一些变量 熟悉一些语句 组合一些函数 C语言——>库  帮你写好放在库中 魔数 凭空变出来的数字,不知道 数字表示的含义,影响代码的可读性. C语音的参数传递 非常特殊,传递的是一个替身. ...

  5. EasyUI篇のDataGrid

    HTML: <table id="dg"></table> 或者 <div id="dg"></div> JS: ...

  6. 关于移动手机端富文本编辑器qeditor图片上传改造

    日前项目需要在移动端增加富文本编辑,上网找了下,大多数都是针对pc版的,不太兼容手机,当然由于手机屏幕小等原因也限制富文本编辑器的众多强大功能,所以要找的编辑器功能必须是精简的. 找了好久,发现qed ...

  7. ps的使用方法

    1.打开原图素材,Ctrl + J把背景图层复制一层,按Ctrl + Shift + U去色,执行:滤镜 > 模糊 > 高斯模糊,数值4,图层混合模式为滤色,图层不透明度改为27%. 2. ...

  8. 谈谈Parser --王垠

    一直很了解人们对于parser的误解,可是一直都提不起兴趣来阐述对它的观点.然而我觉得是有必要解释一下这个问题的时候了.我感觉得到大部分人对于parser的误解之深,再不澄清一下,恐怕这些谬误就要写进 ...

  9. BZOJ 1043 下落的圆盘

    Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求.  Input n ri xi y1 ... rn x ...

  10. Record Locks

    Record Locks 记录锁: 记录锁是一个锁在一个Index记录上,比如 SELECT c1 FOR UPDATE FROM t WHERE c1 = 10; 阻止任何其他事务inserting ...