万能的搜索

223 阅读4分钟

一 :深度优先搜索

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;
}