八皇后--深入理解深度优先搜索


一,深度优先搜索

1.基本概念

深度优先搜索算法(Depth First Search,简称DFS):是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
在这里插入图片描述

2.搜索步骤

(1)首先找到初始节点V0

(2)依此从V0未被访问的邻接点出发,对图进行深度优先遍历

(3)若有节点未被访问,则回溯到该节点,继续进行深度优先遍历

(4)直到所有与顶点V0路径想通的节点都被访问过一次

举个例子,假设我们要从起始点V0出发,使用深度优先搜索算法进行搜索,首先访问V0->V1->V4,走不通了,回溯到上一个结点V1,走V1分支节点V2,路径为V0->V1->V2->V6,走不通了,再回溯到V2,发现没有分支结点,继续回溯到V1,走下一个分支结点V3,然后继续向下搜索。

3.基本模板

void dfs(int step)
{

   if (满足输出条件)
   {
   	for (int i = 1; i <= n; i++) {
   		printf(" 输出解")}
   	printf("\n");
   }
   
   else
   {
   	for (int i = 1; i <= ; i++) {
   		if (满足进一步搜索条件)
   		{
   			为进一步搜索所需要的状态做标记;
   			dfs(step + 1);
   			恢复到打标记前的状态;  //用于回溯到上一步
   		}
   	}
   }
}


二、P1219 [USACO1.5]八皇后 Checker Challenge

在这里插入图片描述

代码如下(示例):

//此代码以
#include<stdio.h>

int a[100], b[100], c[100], d[100];
//a数组表示的是行;
//b数组表示的是列;
//c表示的是左下到右上的对角线;
//d表示的是左上到右下的对角线;
int total;//总数
int n;

void dfs(int i)//搜索与回溯主体
{
    if (i > n)
    {
        if (total <= 2)//保证只输出前三个解,如果解超出三个就不再输出
        {
            for (int k = 1; k <= n; k++)
                printf("%d ", a[k]);//打印前三个解
            printf("\n");
        }
        total++;//计算一共有多少种解法
        return;
    }
    else
    {
        for (int j = 1; j <= n; j++)//
        {
            if ((!b[j]) && (!c[i + j]) && (!d[i - j + n]))
            //确定某一个格子的列和两个对角线都没有被占领,一行一行遍历
            {
                a[i] = j; //标记第i排被占领的位置上,用于遍历输出结果
                b[j] = 1; //标记占领纵列
                c[i + j] = 1; //标记对角线,i+j是这一列对角线共同的特点
                d[i - j + n] = 1;
                dfs(i + 1);//进一步搜索,下一个皇后
                b[j] = 0;
                c[i + j] = 0;
                d[i - j + n] = 0;
                //清除标记,回到上一步重新寻找另一种路线
            }
        }
    }
}
int main()
{
    scanf("%d", &n);
    dfs(1);//第一个皇后
    printf("%d", total);//输出可能的总数
    return 0;
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值