一 :深度优先搜索
1 .深度优先搜索的基本模型
格式如下:
void dfs(int x)
{
判断边界
尝试每一种可能 for(i = 1;i <= n;i++)
{
继续下一步 dfs(x + 1);
}
返回;
}
2 .例题
2.1 :输入一个数n,输出1-n的全排列
代码如下:
#include<stdio.h>
int a[10],book[10],n;
void dfs(int step)
{
int i;
if(step == n+1)
{
for(i = 1;i <= n;i++)
{
printf("%d ",a[i]);
}
printf("\n");
return;
}
for(i = 1;i <= n;i++)
{
if(book[i] == 0)
{
a[step] = i;
book[i] = 1;
dfs(step + 1);
book[i] = 0;
}
}
return;
}
int main()
{
scanf("%d",&n);
dfs(1);
return 0;
}
2.2 : □□□ + □□□ = □□□
代码如下:
#include<stdio.h>
int a[10],book[10],total = 0;
void dfs(int step)
{
if(step == 10)
{
if(a[1]*100 + a[2]*10+a[3]+a[4]*100+a[5]*10+a[6] == a[7]*100+a[8]*10+a[9])
{
total++;
printf("%d%d%d + %d%d%d = %d%d%d \n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
}
return;
}
for(int i = 1;i <= 9;i++)
{
if(book[i] == 0)
{
a[step] = i;
book[i] = 1;
dfs(step + 1);
book[i] = 0;
}
}
return;
}
int main()
{
dfs(1);
printf("%d",total/2);
return 0;
}
2.3 : 迷宫问题
迷宫由n行m列的单元格组成(n <= 50,m <= 50),每个单元格要么是空地,要么是障碍物,求解迷宫.
代码如下:
#include<stdio.h>
int a[51][51],book[51][51],p,q;
int n,m;
int min = 9999999;
void dfs(int x,int y,int step)
{
int tx,ty;
int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
if(x == p&&y == q)
{
if(step < min)
{
min = step;
}
return;
}
for(int k = 0;k <= 3;k++)
{
tx = x + next[k][0];
ty = y + next[k][1];
if(tx < 1||tx > n||ty < 1||ty > m)
{
continue;
}
if(a[tx][ty] == 0&&book[tx][ty] == 0)
{
book[tx][ty] = 1;
dfs(tx,ty,step+1);
book[tx][ty] = 0;
}
}
return;
}
int main()
{
int startx,starty;
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
scanf("%d",&a[i][j]);
}
}
scanf("%d %d %d %d",&startx,&starty,&p,&q);
book[startx][starty] = 1;
dfs(startx,starty,0);
printf("%d",min);
return 0;
}
二 :广度优先搜索
1.什么是广度优先搜索?
之前我们使用了深度优先搜索(dfs)解决了迷宫问题,下面我们使用广度优先搜索(bfs)来求解迷宫问题,广度优先搜索又称宽度优先搜索,是使用层层递进的方式来进行搜索的,我们要创建一个队列,通过一层一层扩展的方法每发现一个点就把这个点加入到队列当中.
2 . 例题
2.1:迷宫问题
使用广度优先搜索求解迷宫问题:
代码如下:
#include<stdio.h>
struct note{
int x;
int y;
int step;
};
int main()
{
struct note que[2501];
int a[51][51] = {0},book[51][51] = {0};
int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
int head,tail;
int tx,ty,startx,starty,p,q,n,m,flag;
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
scanf("%d",&a[i][j]);
}
}
scanf("%d %d %d %d",&startx,&starty,&p,&q);
head = 1;
tail = 1;
que[tail].x = startx;
que[tail].y = starty;
que[tail].step = 0;
tail++;
book[startx][starty] = 1;
flag = 0;
while(head < tail)
{
for(int i = 0;i <= 3;i++)
{
tx = que[head].x + next[i][0];
ty = que[head].y + next[i][1];
if(tx < 1||tx > n||ty < 1||ty > m)
{
continue;
}
if(book[tx][ty] == 0&&a[tx][ty] == 0)
{
book[tx][ty] = 1;
que[tail].x = tx;
que[tail].y = ty;
que[tail].step = que[head].step + 1;
tail++;
}
if(tx == p&&ty == q)
{
flag = 1;
break;
}
}
if(flag == 1)
break;
head++;
}
printf("%d",que[tail - 1].step);
return 0;
}
2.2 :求陆地面积
*0表示海洋,1-9表示陆地,地图是一个10.10的矩阵,从(6,8)开始搜索,现在需要计算出小岛的面积,即有多少个相连的非0格子.
图示:
#include<stdio.h>
struct note{
int x;
int y;
};
int main()
{
struct note que[2501];
int head,tail;
int a[51][51];
int book[51][51] = {0};
int n,m,startx,starty,tx,ty,mx,my,max = 0,sum;
int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
scanf("%d %d %d %d",&n,&m,&startx,&starty);
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
scanf("%d",&a[i][j]);
}
}
head = 1;
tail = 1;
que[tail].x = startx;
que[tail].y = starty;
tail++;
book[startx][starty] = 1;
sum = 1;
while(head < tail)
{
for(int k = 0;k <= 3;k++)
{
tx = que[head].x + next[k][0];
ty = que[head].y + next[k][1];
if(tx < 1||tx > n||ty < 1||ty > m)
{
continue;
}
if(a[tx][ty] > 0&&book[tx][ty] == 0)
{
sum++;
book[tx][ty] = 1;
que[tail].x = tx;
que[tail].y = ty;
tail++;
}
}
head++;
}
printf("%d",sum);
return 0;
}