八皇后问题(适合初学者的写法)C语言

article/2025/9/10 19:50:37

什么是八皇后问题:

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。


 PS:这篇文章想法思路简单,代码量长,适合初学者学习,能更好的的理解这个问题



一、思路分析

首先我们思考一下,我们是应该一个一个的放置皇后还是该先把八个皇后全部放入棋盘然后在进行移动操作?我们是应该一个一个的放置皇后的。所谓牵一发而动全身,当八个皇后全部放入棋盘后,我们每移动一个皇后就会导致其他皇后的位置都得移动,从而导致了运算过程的冗杂重复,也导致了计算时间的增加和内存的浪费,对于追求效率的C语言来说这是不可取的,所以我们选择一个一个的放置皇后。
这样操作有什么优点呢?每当我们在选择移动一个皇后的位置的时候,其它已经放置好了的皇后的位置是不需要移动的,如果当某个皇后在属于它的行都不满足条件时,我们才需要回溯过去改变上一个皇后的位置。我们需要的就是循环的进行回溯操作,直到所有的皇后都放置完成,这样计算机的每一步操作都是有用的,不再是无用功。


我们来看一下回溯法

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
 



二、代码实现过程



1.定义阶段

对于一个8*8的棋盘,我们很多人都会第一时间想到初始化一个二维数组来保存这个棋盘。但其实没有必要。因为八个皇后每一行只能有一个占据东宫的位置,所以我们只需要定义一个一维数组,每一个数字来表示皇后所在的列数即可。



2.皇后的摆放

我们首先要定义一个计数器,来记录每一次成功的8位皇后摆放方法

int count=0;

然后我们先摆放第一个皇后,再摆放第二个皇后的时候需要考虑
皇后与皇后不会再同一行上不会在直角线上(成45°或135°)(定义的一维数组已经保证每一行只会有一个皇后)。所以我们在每摆放一个新的皇后时都要与前面的皇后进行if语句的判断

for (int q1 = 0; q1 < 8; q1++)  //第一个皇后{for (int q2 = 0; q2 < 8; q2++) //第二个皇后{if (q1 == q2 || q1 == q2 + 1 || q1 == q2 - 1) //不在同一列,不成对角线{continue;}}}

同理:在摆放第三个皇后的时候需要与第一个第二个皇后进行比较判断

	for (int q1 = 0; q1 < 8; q1++){for (int q2 = 0; q2 < 8; q2++){if (q1 == q2 || q1 == q2 + 1 || q1 == q2 - 1){continue;}for (int q3 = 0;q3 < 8; q3++){if (q1 == q3 || q1 == q3 + 2 || q1 == q3-2|| q2 == q3 || q2 == q3 + 1|| q2 == q3 - 1){continue;}}}}

continue如果if不成立那么返回上一层循环,对于上一个皇后的位置重新选择

可以按照上面思路自己写一写!


最后奉上完整版代码和实现 :

int main()
{int count = 0;//计数器for (int q1 = 0; q1 < 8; q1++){for (int q2 = 0; q2 < 8; q2++){if (q1 == q2 || q1 == q2 + 1 || q1 == q2 - 1){continue;}for (int q3 = 0;q3 < 8; q3++){if (q1 == q3 || q1 == q3 + 2 || q1 == q3-2|| q2 == q3 || q2 == q3 + 1|| q2 == q3 - 1){continue;}for (int q4 = 0; q4 < 8; q4++){if (q1 == q4 || q1 == q4 + 3 || q1 == q4 - 3 || q2 == q4 || q2 == q4 + 2|| q2 == q4- 2 || q3 == q4 || q3 == q4 + 1 || q3== q4- 1){continue;}for (int q5 = 0; q5 < 8; q5++){if (q1 == q5 || q1 == q5 + 4 || q1 == q5 - 4 || q2 == q5 || q2 == q5 + 3|| q2 == q5 - 3 || q3 == q5 || q3 == q5 + 2 || q3 == q5- 2 || q4 == q5 || q4 == q5 + 1 || q4 == q5 - 1){continue;}for (int q6 = 0; q6 < 8; q6++){if (q1 == q6 || q1 == q6 + 5 || q1 == q6 - 5|| q2 == q6 || q2 == q6 + 4 || q2 == q6 - 4|| q3 == q6 || q3 == q6 + 3 || q3 == q6 - 3|| q4 == q6 || q4 == q6 + 2 || q4 == q6 - 2|| q5 == q6 || q5 == q6 + 1 || q5 == q6 - 1){continue;}for (int q7 = 0; q7 < 8; q7++){if (q1 == q7 || q1 == q7 + 6 || q1 == q7 - 6|| q2 == q7 || q2 == q7 + 5 || q2 == q7 - 5|| q3 == q7 || q3 == q7 + 4 || q3 == q7 - 4|| q4 == q7 || q4 == q7 + 3 || q4 == q7 - 3|| q5 == q7 || q5 == q7 + 2 || q5 == q7 - 2|| q6 == q7 || q6 == q7 + 1 || q6 == q7 - 1){continue;}for (int q8 = 0; q8 < 8; q8++){if (q1 == q8 || q1 == q8 + 7 || q1 == q8 - 7|| q2 == q8 || q2 == q8 + 6 || q2 == q8 - 6|| q3 == q8 || q3 == q8 + 5 || q3 == q8 - 5|| q4 == q8 || q4 == q8 + 4 || q4 == q8 - 4|| q5 == q8 || q5 == q8 + 3 || q5 == q8 - 3|| q6 == q8 || q6 == q8 + 2 || q6 == q8 - 2|| q7 == q8 || q7 == q8 + 1 || q7 == q8 - 1){continue;}count++;printf("%d,%d,%d,%d,%d,%d,%d,%d\n", q1, q2, q3, q4,q5, q6, q7, q8);                        }}}}}}}}printf("一共有%d种方法", count);return 0;
}

程序实现:

将所有摆放方式都打印出来,打印每一个皇后所在的列下标。因为结果太多我就截取了最后面的截图。



总结:

这篇我八皇后我尽量写的通俗为了让初学者很好的理解这个问题,因此代码冗杂但是核心算法很好理解,当然也有其他的写法函数啊什么的更简单,但是对于新手很不友好,所以我开篇强调了适用于新手!!整体思路就是循环比较,回溯上一级判断 如果对你有帮助就点个赞吧!


http://chatgpt.dhexx.cn/article/LitDsRaK.shtml

相关文章

八皇后问题,秒懂递归回溯(有图详解|c语言)

目录 &#x1f478;&#x1f3fb;前言 &#x1f478;&#x1f3fb;题目介绍 &#x1f478;&#x1f3fb;引入&#xff1a; &#x1f478;&#x1f3fb;解决思路&#xff1a; &#x1f478;&#x1f3fb;理论存在&#xff0c;实践开始&#xff01; &#x1f478;&#x1f…

利用ngrok实现域名映射局域网ip

前言 相信很多开发者都有这样的需求&#xff0c;需要让外网访问你本地的服务器&#xff0c;方便调试本地代码&#xff0c;或者让别人体验到自己做的应用。那么这时&#xff0c;我们需要做的就是将我们本地的端口映射到一个外网的端口上&#xff0c;也就是内网穿透。常见的解决…

python调用手机摄像头,实现实时调用摄像头,需要你的电脑和手机在同一个局域网内

1、android手机上安装一款APP&#xff1a;IP摄像头&#xff0c;app的图片如上图 2.调用代码如下 import cv2cv2.namedWindow("camera", 1) # 开启ip摄像头 video "http://admin:admin10.0.0.32:8081/" # 此处后的ipv4 地址需要改为app提供的地址 cap c…

02、处于不同局域网下的Socket通信(网络部分理论知识)

目录 一、服务器 1、服务器的种类和功能 2、服务器的操作系统 3、IIs、Apache、Tomcat 4、云服务器 弹性云服务器&#xff08;Elastic Cloud Server&#xff0c;ECS&#xff09; 云服务器安全组 二、OSI七层模型与TCP/IP五层模型 三、外网、内网、公网、私网 内网穿透…

使用wireshark抓取聊天信息(局域网内的udp通信)

文章目录 1&#xff0c;实验目的2&#xff0c;实验操作3&#xff0c;总结4&#xff0c;附件 1&#xff0c;实验目的 1.分析这程序所采用的是udp还是tcp 2.在抓取包中找到窃取到的聊天信息 (英文字符和汉字可能经过了某种编码转换&#xff0c;数据包中不是明文) 3.如果是网络连…

安装黑群晖找不到局域网电脑_黑群晖洗白太复杂?我用蒲公英P5轻松实现

前言: 随着网盘时代的结束,剩下的网盘供应商又开启了垄断方式,所以越来越多的小伙伴开始自己组自己的家庭NAS网络存储服务器。比如笔者的一个好基友就是如此。其实开始笔者是想让他直接一步到位,买群晖或者铁威马的NAS,在放入硬盘就可“一劳永逸”。然而,这个小伙伴看到了…

内网穿透实现局域网内搭建私服务器

使用云服务器实现内网穿透。内网里建立一台老旧win机专门用来挂pt&#xff0c;在上面存储视频和软件&#xff0c;而后映射在外网中&#xff0c;通过手机和电脑随时随地的下载和在线观看win机上的视频和文件。 1、修改ssh的默认端口 在公网中使用常用软件的默认端口会导致自己的…

局域网终结者_p2p终结者怎么安装使用 p2p终结者安装使用方法【介绍】

p2p终结者是一款局域网控制软件&#xff0c;他的主要功能就是控制和限制同一个局域网内其它的上网用户&#xff0c;如限制不让别人上QQ&#xff0c;不让别人开网页和不让别人下载&#xff0c;只要他和你在同一网之内你就可以控制他&#xff0c;并且神奇的是&#xff0c;不需要动…

Kali Linux-MSF远控局域网手机

前言 严正声明&#xff1a;本文仅限于技术讨论与分享&#xff0c;严禁用于非法途径。 本文目的&#xff1a;演示如何借助Kali Linux系统的Metasploit渗透测试框架生成远程控制程序&#xff0c;然后感染局域网内的Android手机&#xff0c;从而实现对目标手机数据的读取、音频的…

超级眼局域网监控软件 员工禁止软件 可以控制时间段

第一步&#xff1a; 下载超级眼局域网监控软件&#xff1a; 将经理端安装在管理者的电脑上&#xff0c;员工端安装在需要被监控者的电脑上。 第二步&#xff1a;在经理端电脑上操作。打开管理端软件&#xff0c;扫描所有的被控电脑。然后选择需要管理的电脑&#xff08;可以全选…

Kali使用Netdiscover探测局域网中存活主机

1、netdiscover介绍 Netdiscover 是一个主动/被动的ARP 侦查工具。使用Netdiscover工具可以在网络上扫描IP地址,检查在线主机或搜索为它们发送的ARP请求。 2、 主动模式:主动模式顾名思义就是主动的探测发现网络内主机,但是这种方式往往会引起网络管理员的注意。 打开Kali终…

如何避免计算机被别人共享,win7如何防止别人偷窥电脑 win7防止别人偷窥电脑操作方法...

我们都知道在win7系统中&#xff0c;可以设定开机密码或者屏保密码来防止我们的电脑被别人使用&#xff0c;不仅win7系统可以设置开机密码或者屏保密码&#xff0c;其他版本的系统也是可以设置的&#xff0c;那么win7如何防止别人偷窥电脑呢?下面为大家介绍win7防止别人偷窥电…

【时间之外】监控你的电脑只需8步

最近某安全厂商很火&#xff0c;很多离职员工都是被这套系统抓出来的。其实原理很简单&#xff0c;本文就用很多人都用过的kali系统&#xff0c;告诉你&#xff0c;想要控制你的电脑有多简单&#xff01; 网上的文章很多&#xff0c;如这篇&#xff0c;Kali攻防&#xff0c;写…

详细介绍别人电脑访问到自己电脑运行的项目

文章目录 让别人远程访问你的代码网站项目或临时演示你的项目给客户的方式详解 引言一、创建一个你想要别人访问的项目二、明确你想要将这个网站或者项目存放的地方 终端分类服务器设备WEB服务器三、部署我们的网页 本地部署流程进入浏览器输入网址访问获取本机的IP地址&#…

监控手机屏幕、监控电脑屏幕方案

一&#xff1a;手机投屏 实时监控多个手机屏幕&#xff08;<3台&#xff09; ApowerMirror软件&#xff0c;终生179&#xff0c;可同时连接3部手机 网络环境&#xff1a;电脑与测试手机需要在同一个WiFi网络环境下。(要求手机型号不同) 软硬件环境&#xff1a;电脑和手机分别…

基于VC++的局域网内主机监控系统设计与实现

局域网内主机监控系统 目录 引言 2 1.1 编写目的 2 1.2 项目背景 2 1.3 课题内容和要求 3 1.4 名词解释 4 参考文献 4需求分析 5 2.1 现有系统概述 5 2.2 对新系统的要求 5 2.3 系统要求 6 2.4 对功能的规定 6 2.5 对性能的规定 6 2.6 运行环境规定 7 2.6.2 软件配置 7系统架…

同一个局域网之内,如何远程控制对方的电脑而且不用对方同意

条件&#xff1a; 1、同一个局域网之内&#xff1b; 2、远程控制对方电脑&#xff1b; 3、不用对方做任何操作&#xff08;QQ远程控制需要对方点击同意才能进行远程&#xff09; 具体操作如下&#xff1a; 一、关闭对方电脑的防火墙 二.允许电脑被对方远程 计算机-属性-远…

详解LinkedList

目录 一、介绍 二、源码分析 1、LinkedList实现的接口 2、LinkedList中的变量 3、LinkedList的构造方法 &#xff08;1&#xff09;无参构造方法 &#xff08;2&#xff09;带集合参数的构造方法 4、LinkedList中的重要方法 &#xff08;1&#xff09;静态内部类Node …

java linkedlist 节点_JAVA学习-LinkedList详解

1.定义 实现List接口与Deque接口双向链表&#xff0c;实现了列表的所有操作&#xff0c;并且允许包括null值的所有元素&#xff0c;对于LinkedList定义我产生了如下疑问&#xff1a; 1.Deque接口是什么&#xff0c;定义了一个怎样的规范? 2.LinkedList是双向链表&#xff0c;其…

LinkedList入门教程

目录 LinkedList是什么&#xff1f;LinkedList的使用创建对象添加元素删除元素获取长度排序 常用方法 LinkedList是什么&#xff1f; LinkedList是一种数据结构&#xff0c;它由节点组成&#xff0c;每个节点包含一个值和一个指向下一个节点的指针。这种数据结构非常适合插入和…