N 皇后问题

N皇后问题, 是一个很经典的递归算法.(recursion), 题目来自国际象棋玩法。

一、问题描述:

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
在n×n的棋盘上放置n个皇后,任何2个皇后不能放在同一行或同一列或同一斜线上。
输入:
    给定棋盘的大小n (n≤ 13)
输出:
   输出有多少种放置方法,及各种解。
二、解题思路:
首先用 i  (1<= i <= n)表示行,代表 N 个皇后处在不同行上。
再用 x(i)表示列, 代表第 i 个皇后放在 x(i)列上 。
这样来看约束条件:
 因为i 已经代表了N个皇后处在不同行上,所以这点可以不用考虑。
如果x(k) = x(i), 那就表示皇后k和皇后i处在同一列, 要各个皇后处在不同列上,就需要 x[k] != x[i].
如果皇后k 和皇后i 处在同一斜线上,那必须有 i + x(i) = k + x(k), 或i - x(i) = k - x(k),
也就是同一斜线上的(X,Y)坐标, 要么X + Y相等(左高右低), 要么X-Y相等(左低右高)。
合并两个公式,也就是 |i -k|  = |x(i) - x(k)| ,    绝对值用函数abs()即可。

如下图:


这样再利用回溯法,就可以找出解了:
1. 递归法:
#include<stdio.h>
#define N 15

int n; //queuen number
int sum = 0; // solution number
int x[N]; // queen column


int place(int k) //try to put new queen k on x[k].
{
        int i;
        for(i=1;i<k;i++)
                if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i])
                        return 0;
        return 1;
}


int queen(int t)
{
        int j;

        if(t>n && n>0) //when t > n, solution + 1
                sum++;
        else
                for(j=1;j<=n;j++) {
                        x[t] = j;   //queen t on j column
                        if(place(t))  //if return true, place another queen.
                                queen(t+1);
                }
        return sum;
}

int main()
{
        int t;

        scanf("%d",&n);
        t = queen(1);
        if(n == 0)                    //if n = 0, solution = 0.
                t = 0;
        printf("%d\n",t);

        return 0;
}
2. 迭代法, 不使用递归方式,
#include<stdio.h>
#define N 15

int n;
int sum = 0;
int x[N];

int place(int k)
{
        int i;
        for(i=1;i<k;i++)
                if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i])
                return 0;
        return 1;
}

int queen()
{
        x[1] = 0;
        int t=1;
        while(t>0)
        {
                x[t]+=1;
                while(x[t]<=n && !place(t))
                        x[t]++;
                if(x[t]<=n) {
                        if(t == n)
                                sum++;
                        else
                                x[++t] = 0;
                } else
                        t--;
        }
        return sum;
}

int main()
{
        int t;
        scanf("%d",&n);
        t = queen();
        printf("%d",t);
        return 0;
}
在这里我们可以看到,递归回溯非常简单,结构很清晰,但它有一个潜在的问题存在,即当随着变量n的增大,递归法的复杂度也将成几何级增长,也有可能会出现重复的情况,所以我们在解决问题时,如果能用迭代法解决,最好还是不要用递归法,除非你已经对这个递归了如指掌了。
 
  通过这个N皇后问题,我想大概已经把回溯法讲得很清楚了吧,回溯法得到的解展开就是一个树,很多方法都是可以通过回溯法来解决的,效率很高,但如果基数过大的话,回溯法就显得不是那么适用了,这也是回溯法的弱势吧。
比如说这个N皇后问题,好像当n>60的时候,回溯法就不能完全地解决问题了,这时可以考虑用概率算法来解决,它可以解决很大的基数,只不过结果不是很精确而已。
所以我们在面对一个问题时,具体是使用什么算法还是要结合实际情况来考虑的,目的都是更方便、更准确地解决问题。




本指南详细阐述基于Python编程语言结合OpenCV计算机视觉库构建实时眼部状态分析系统的技术流程。该系统能够准确识别眼部区域,并对眨眼动作与持续闭眼状态进行判别。OpenCV作为功能强大的图像处理工具库,配合Python简洁的语法特性与丰富的第三方模块支持,为开发此类视觉应用提供了理想环境。 在环境配置阶段,除基础Python运行环境外,还需安装OpenCV核心模块与dlib机器学习库。dlib库内置的HOG(方向梯度直方图)特征检测算法在面部特征定位方面表现卓越。 技术实现包含以下关键环节: - 面部区域检测:采用预训练的Haar级联分类器或HOG特征检测器完成初始人脸定位,为后续眼部分析建立基础坐标系 - 眼部精确定位:基于已识别的人脸区域,运用dlib提供的面部特征点预测模型准确标定双眼位置坐标 - 眼睑轮廓分析:通过OpenCV的轮廓提取算法精确勾勒眼睑边缘形态,为状态判别提供几何特征依据 - 眨眼动作识别:通过连续帧序列分析眼睑开合度变化,建立动态阈值模型判断瞬时闭合动作 - 持续闭眼检测:设定更严格的状态持续时间与闭合程度双重标准,准确识别长时间闭眼行为 - 实时处理架构:构建视频流处理管线,通过帧捕获、特征分析、状态判断的循环流程实现实时监控 完整的技术文档应包含模块化代码实现、依赖库安装指引、参数调优指南及常见问题解决方案。示例代码需具备完整的错误处理机制与性能优化建议,涵盖图像预处理、光照补偿等实际应用中的关键技术点。 掌握该技术体系不仅有助于深入理解计算机视觉原理,更为疲劳驾驶预警、医疗监护等实际应用场景提供了可靠的技术基础。后续优化方向可包括多模态特征融合、深度学习模型集成等进阶研究领域。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值