八皇后问题详解(附详细代码)

4 篇文章 1 订阅
3 篇文章 0 订阅
本文介绍了八皇后问题的历史背景及其规则,即如何在8×8棋盘上摆放8个皇后,使得它们互不攻击。通过分析横坐标、纵坐标和对角线的关系,提出使用深度优先搜索来解决此问题。提供的C++代码实现中,使用了标记数组来跟踪已放置的皇后,确保不会在同一行、列或对角线上。文章最后鼓励读者尝试解决更复杂的N*N棋盘上摆放n个棋子的问题。
摘要由CSDN通过智能技术生成

八皇后问题详解

著名的八皇后问题是由棋手马克斯·贝瑟尔在1848年提出来的,要求在 8 × 8 的棋盘上摆放8个皇后,使”皇后“们不能互相攻击 ,当任意两个皇后都不处于同一行、同一列或同一条斜线上时就不会相互攻击,即为目标解。

例如下图:

读完上面的内容,想必您已经对此问题有了一定的认识,也就是我们需要在一个8 × 8的矩阵中摆放8个不在同一行,不在同一列,并且不在同一对角线上的棋子,计算出有多少种摆放的方法。

我们知道在一个矩阵中的同一个右对角线上所有元素的横坐标和纵坐标之和是一个定值,即横坐标与纵坐标之和,而同一左对角线上的所有元素的坐标也有特点,即都是纵坐标与横坐标的差值。可以看下图:

那么这个时候,用深度优先搜索就能够轻易的解决问题了,以下是我的代码,代码里包含详细注释,可以根据注释来理解。

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
//标记数组
bool vis[30]={false};//列的标记数组,初始为false
bool lr[30]={false};//左对角线的标记数组,初始为false 
bool fr[30]={false};//右对角线的标记数组,初始为false 

int cnt=0;//记录所有摆放方法的数量
const int n = 8;

bool judge(int x,int y)//判断当前位置是否能摆放皇后,当前位置为(x,y)
{
    if(vis[y] || lr[y-x+n] || fr[x+y])
        return false;
    return true;
}
void dfs(int x)
{
    if(x==n)//结束条件:摆放的个数达到n个,在这里即8个
    {
        cnt++;
        return ;
    }
    
    for(int i=1;i<=n;i++)//遍历所有情况,i表示列,即纵坐标
    {
        if(!judge(x,i))//判断条件,如果不能摆放就continue
        	continue;
      	  //标记已走过 
        vis[i]=true;
        lr[i-x+n]=true;
        fr[x+i]=true;
        dfs(x+1);//在i行已经有棋子后开始下一行
        //撤回标记,不影响下一次的落棋
        vis[i]=false;
        lr[i-x+n]=false;
        fr[x+i]=false;
    }
    return ;
}
int main()
{
    dfs(0);
    cout<<cnt<<endl;
    return 0;
}

这个八皇后是最基础的部分,算是如个门,知道是个咋回事,如果这题懂了之后,推荐可以做一下相关的扩展题目,比如N*M的棋盘下n个棋子等等,希望此篇题解对您有所帮助,再见。

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

huafeng88

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

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

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

打赏作者

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

抵扣说明:

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

余额充值