DFS即深度优先搜索算法(Depth-First-Search)
我的理解就是找一条路一直走到黑,不行就一步步回退。常用递归来实现
下面用几道题目进行理解:
黑白图像
输入一个n*n的黑白图像(1表示黑色,0表示白色),任务是统计其中八连快的的个数,如果两个格子有公共的边或者定点就说他们属于一个八连快。
如图中n为6,有三个八连块。
题目解析:
这里主要讲一下怎么判断某一处的八连块,当找到一个黑点,则继续搜索其旁边的八个点,若为黑则继续递归,否则返回,并用vis[]数组记录遍历状态。
算法实现:
#include<stdio.h>
#include<string.h>
const int MAXN =100;
int mat[MAXN][MAXN], vis[MAXN][MAXN];
char s[MAXN];
int n;
void dfs(int x, int y)
{
if(!mat[x][y] || vis[x][y]) return;
vis[x][y] = 1;
dfs(x-1, y-1);
dfs(x-1, y);
dfs(x-1, y+1);
dfs(x, y-1);
dfs(x, y+1);
dfs(x+1, y-1);
dfs(x+1, y);
dfs(x+1, y+1);
}
void init()
{
memset(mat, 0, sizeof(mat));
memset(vis, 0, sizeof(vis));
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 main()
{
init();
int count = 0;
scanf("%d", &n);
for(int i = 0; i <= n; i++)
for(int j = 0; j<= n; j++)
if(!vis[i][j] && mat[i][j]) {count++; dfs(i,j);}
printf("%d\n", count);
}
DFS实现八皇后问题
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
int mat[8][8];
int ans = 0;
bool check(int row,int col)
{
for(int i=0;i<row;i++)
{
//不能同列
if(mat[i][col])
{
return false;
}
//不能在同一对角线
for(int j=0;j<8;j++)
{
if(mat[i][j])
{
if( fabs(i - row) - fabs(j - col) == 0)
{
return 0;
}
else
{
break;
}
}
}
}
return true;
}
int dfs(int row)
{
if(row>=8)
{
ans++;
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
printf("%d ",mat[i][j]);
}
printf("\n");
}
printf("\n");
}
for(int col=0;col<8;col++)
{
if(check(row,col))
{
mat[row][col] = 1;
dfs(row + 1);
mat[row][col] = 0;
}
}
}
int main()
{
memset(mat,0,sizeof(mat));
dfs(0);
printf("total = %d\n",ans);
return 0;
}
本文参考:七月算法, 八皇后问题DFS解法 .