N皇后问题——DFS+回溯剪枝

N皇后问题是八皇后问题的拓展,N皇后问题要满足N行N列的方格里面放N个皇后,保证不同行、不同列、不同对角线

分析:
可以用暴力,对规模较小的皇后问题当然可以,判断是否可以放置的条件甚至可以一步到位,但是N皇后问题的规模就可能很大了,暴力遍历行不通。

利用循环可以一行一行的做主循环,那么我们就在这个主循环下面保证不同列、不同对角线,以此来判断是否可以放置皇后。完成后保存结果继续对下一行施行该操作,这就满足了递归思想。

关键是剪枝,一定要在放置皇后之前判断是否可以放置,如果没有必要放置就不在此基础上做下一层递归,避免不必要的递归造成复杂度变大。

N皇后问题(N<=10)的代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,tot=0;//tot用来记录N皇后问题的可实现个数
int col[12]={0};//用来模拟每一行的皇后放置情况
//例如col[i]=j表示在第i行的第j列放置了皇后
bool check(int c,int r){//检查是否和之前放置的皇后冲突
    for(int i=0;i<r;i++)//不同行已经保证了
        if(col[i]==c||(abs(col[i]-c)==abs(i-r)))//判断是否不同列、对角线
            return false;
    return true;
}
void DFS(int r){
    if(r==n){
        tot++;
        return;
    }
    for(int c=0;c<n;c++)//在每一列放置皇后
        if(check(c,r)){//检查这一行的第c列能否放置皇后
            col[r]=c;//可以的话就放置,并进入下一层递归
            DFS(r+1);
        }
}
int main(){
    int ans[12];
    for(n=0;n<=10;n++){//要注意提前打表,否则会超时
        memset(col,0,sizeof(col));
        tot=0;
        DFS(0);
        ans[n]=tot;
    }
    while(~scanf("%d",&n)){
        if(!n)break;
        printf("%d\n",ans[n]);
    }
}

哈密顿回路回溯法是一种用于解决图论中的经典问题——寻找一个给定图中是否存在哈密顿回路(即一条经过每个顶点恰好一次且最后回到起点的闭合路径)的算法。其特点主要包括: 1. **递归搜索**:采用深度优先搜索(DFS)的策略,从图的一个顶点开始,尝试沿着未访问过的边扩展路径。 2. **剪枝策略**:当发现不可能形成回路的情况(如当前路径已经包含了所有的顶点但尚未返回起点),会回溯到上一步,尝试其他路径。 3. **局部搜索**:在每次扩展路径时,通常只考虑相邻的节点,然后逐步增加路径长度。 4. **分支与限界**:由于搜索空间巨大,可能需要设置一些启发式规则或限界条件来减少搜索范围。 n皇后问题是另一个经典的回溯算法应用,目标是在一个n×n的棋盘上放置n个皇后,使得任意两个皇后都不在同一行、同一列或对角线上。其特点包括: 1. **问题状态表示**:用一个二维数组或位数组表示棋盘状态,0代表空格,1代表皇后。 2. **递归推进**:从第一行开始,尝试在每一行的每个位置放置皇后,然后递归地处理下一行。 3. **冲突检测**:在放置皇后时检查是否与之前放置的皇后冲突,如有冲突则回溯。 4. **剪枝优化**:可以使用回溯技巧避免无效的搜索,比如在某一列无法放置皇后时,直接跳过该列剩余的所有位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布布要成为最负责的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值