数据结构与算法 — 八皇后问题(回溯算法)

article/2025/9/15 9:53:53

问题描述

在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
在这里插入图片描述
假设上图中红点为一个皇后的位置,那么他的同行,列,斜线上都不能再放置其他皇后(也就是红线覆盖的位置)
在这里插入图片描述
此图为八皇后问题的其中一种解法,目前已经有人用图论的方法解出92种结果。

思路分析

一、如何实现

这就和我们人做这种题的时候一样,所有放置皇后的过程都是一行一行来的,首先将第一行的皇后放在第一个位置,然后再看第二行。最开始也是将第二行的皇后放在第二行的第一个位置,发现冲突了,然后在移到第二行的第二个位置,还是冲突了,就再次移动,直到不与之前的皇后冲突,就开始进行下一行的放置以此类推。如果遇到了一整行都是与之前放置的皇后冲突的话就会从上一行里进行改变(比如在放第8行的皇后时,发现所有位置都不成立,那么他就会到第7行中,寻找符合的位置,再不行就到第6行里找,以此类推、、、)。

二、保存结果

一般这种图,我们都是用二维数组来表示的。但是这里我们可以使用普通的数组来表示。创建一个array数组,长度为8。array={2,5,1,6,0,3,7,4},这就代表着一种解法。下标为0的值为2,就代表第1行的第二个位置放置了一个皇后,下标为1的值为5,就代表第二行的第5个位置放置了一个皇后。以此类推。。。算法结束后,我们只需要遍历数组就可以得到解法。

三、检验是否冲突

这个问题中,检验是否冲突是很重要的一步。同行与同列都是很容易检验的。因为是普通的数组,不同的下标就代表着不同的行,所以这本身就解决了皇后同行的问题。检验是否同列,只需要在放入新皇后的时候,看看它的值,是否与其他下标的值相同,相同则表示他们在同一列。
检验是否在同一斜线也很容易理解,如果他们在同一斜线,那么这条斜线的斜率就为1,这两个皇后的行之差的绝对值与列之差的绝对值相同那么就是在同一直线上。你也可以把它想作是一个等腰RT三角形,它的两个直角边相同,他们两个肯定就是在同一直线上。
在这里插入图片描述
如图,绿点和红点分别是两个皇后,他们的行坐标之差的绝对值为abs(4-2)=2。列坐标之差的绝对值为abs(2-4)=2。两者相等那么就代表他们处于同一斜线,不能成立。

代码实现

public class Queens {int max = 8; //一共8个皇后,定义初始值int[] array = new int[max];static int count=0;public static void main(String[] args) {Queens queens = new Queens();queens.put(0);System.out.println(count);}//结果输出方法private void print() {for (int i = 0; i < array.length; i++) {System.out.print(array[i]);}System.out.println();}//检查放到第n个皇后时,是否与之前的皇后冲突private boolean check(int n) {for (int i = 0; i < n; i++) {if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[i] - array[n])) {return false;}}return true;}//放置第n个皇后private void put(int n){if (n == max){ //因为下标是从0开始的,所以当n=8时代表再放就是第九个皇后了,就是已经放完了8个。直接打印结果即可。count++;print();return;}for (int i=0;i<max;i++){array[n] = i;//先把这个皇后放到此行的第一个位置if (check(n)){//检查放第n个皇后时是否冲突,不冲突的话就继续放置第n+1个。put(n+1);}}//如果冲突了就继续执行 array[n] = i这就相当于这一行的这个位置是不行的,我们要试试下个位置了}
}

运行结果

在这里插入图片描述
因为解法一共有很多很多种,这里只截取了部分,但是最后输出了解法总个数为92个。


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

相关文章

数据结构与算法-- 八皇后问题(多种实现方案)

八皇后问题解法一(排列筛选法) 本篇我们承接上一篇中的思想&#xff0c;想到了一个经典的算法题&#xff0c;八皇后问题&#xff1a;题目&#xff1a;在8*8的国际象棋上摆放8个皇后&#xff0c;使得其互相不能攻击&#xff0c;即任意两个换后不能在同一行&#xff0c;同一列&a…

C语言开方问题求助

求助&#xff1a; 使用的是Devcpp进行的编程尝试 在写程序的时候遇到了个问题&#xff0c;运行后结果显示为1#j 后来在朋友的帮助下改正了程序&#xff0c;解决了错误。之后的话&#xff0c;我按照我朋友的改正过的程序自己再重新打了一遍&#xff0c;结果运行后的结果还是显示…

C语言笔记

目录 基础... 3 基本类型数据... 5 定义变量... 6 进制... 6 ASCII&#xff08;阿斯克码&#xff09;... 7 输入输出... 8 printf&#xff08;&#xff09;将变量的内容输出到显示器上... 8 scanf &#xff08;&#xff09;[通过键盘将数据输入到变量中] 9 运算符... …

c语言 大数开方,大数加法之C语言函数法(只有正数版)

由于某些原因&#xff0c;我于今天2017-4-19将我的博文搬到博客园了&#xff0c;以后我就在这里扎根了。 之前想过在博客写文章方便日后复习&#xff0c;但一直未能实现&#xff0c;所以&#xff0c;现在这篇是我个人人生中第一篇博客&#xff0c;所以写博客完全没经验&#xf…

开平方的快速算法(C代码)

目录&#xff1a; 一、牛顿迭代法 二、采用移位、加减法、判断和循环实现开平方 三、效率远高于牛顿迭代法开平方法 1、原理 2、实现代码 四、卡马克快速开平方算法(推荐) 1、C-Free模拟验证卡马克开平方 2、移植到实际的项目 3、卡马克快速开平方的由来 1&#xff0…

windows 区域截屏以及延迟截屏

提起在Windows&#xff0c; 我们都会用到截屏功能&#xff0c;今天论述一下window 10系统自带的截图应用Snipping Tool 打开Snipping Tool 找到任务栏下的放大镜图标&#xff0c;点击 在下方输入snipping&#xff0c;会在左侧找到截图软件Snipping Tool&#xff0c;点击可进入…

小米手机解决此区域不可截屏

小米手机解决此区域不可截屏 无意中暂停视频弹出消息&#xff0c;想试试可不可以截屏竟然可以截屏&#xff0c;但是视频一播放就截屏不了了&#xff0c;录屏也是&#xff0c;直接变黑或者是直接提示弹窗&#xff0c;嘻嘻嘻嘻小米bug还是有好处滴

浏览器网页截屏实用小技巧

浏览器开发者工具中自带的截屏太方便了&#xff01; 打开开发者工具&#xff0c;输入 ctrl shift P 快捷键&#xff0c;输入screenshot&#xff0c;出现了四个选项&#xff0c;分别是&#xff1a; 1.area screenshot - 区域截图 2.full size screenshot - 对浏览器所有内容…

如何利用计算机截屏快捷键,电脑怎么截图 电脑选区域截图怎么截 电脑截图快捷键是什么...

电脑怎么截图 按照操作上从易到难的顺序&#xff0c;给你推荐五种截屏方式 &#xff1a; 第一种&#xff1a;Ctrl PrScrn 使用这个组合键截屏&#xff0c;获得的是整个屏幕的图片; 第二种&#xff1a;Alt PrScrn 这个组合键截屏&#xff0c;获得的结果是 当前窗口的图片; 第三…

iOS 截屏指定区域

转自&#xff1a;链接&#xff1a;https://www.jianshu.com/p/39db0fa66c0e 指定截屏代码实现 全屏截图效果 全屏截图效果 指定区域截屏效果 指定区域截屏效果 这里先上代码&#xff0c;代码后面有相关方法的解释第一种方法代码下载 /**创建一个基于位图的上下文&#xff0…

windows如何截屏

截屏是我们平时工作或记录常用的操作&#xff0c;不过有人不知道怎么用系统截屏&#xff0c;今天&#xff0c;小编带来了系统的几种截屏&#xff0c;让我们来看看吧&#xff01; 一、快捷键截图 1. Win shift S&#xff1a;可以选择截图区域的大小&#xff0c;CtrlV粘贴在w…

Android 任意区域截屏

1、全屏截图 Android其实可以做到任意区域截屏&#xff0c;不过我们先来看看整个屏幕截图代码&#xff0c;相信大家很熟悉&#xff0c;代码如下 View decorView activity.getWindow().getDecorView(); decorView.setDrawingCacheEnabled(true); view.buildDrawingCache(); /…

snipaste 固定位置截屏

原文参考&#xff1a; snipaste怎么固定位置截图&#xff0c;如何统一大小截图 一、电脑点击【snipaste】&#xff0c;或者点击键盘的“F1”。 二、在图片&#xff0c;根据自己的需求&#xff0c;画出截图的位置和大小&#xff0c;比如&#xff1a;本篇是500*296。 三、点击右…

JavaScript实现浏览器特定区域截屏和下载功能

JavaScript实现浏览器特定区域截屏功能 需求介绍尝试一&#xff1a;使用Jtopo.js自带的保存图片方法&#xff08;不能对资源进行下载&#xff09;尝试二&#xff1a;对saveImageInfo进行改写&#xff08;功能能用&#xff0c;但是会因为跨域问题污染canvas&#xff09;&#xf…

Unity中的截图方法(包括全屏截图、区域截图、Camera截图和摄像头截图)

Unity中的截图方法&#xff08;包括全屏截图、区域截图、Camera截图和摄像头截图&#xff09; Application.CaptureScreenshotScreenCapture Texture2D.ReadPixels视口截图RenderTexture&#xff08;Camera截图&#xff09;WebCamTexture&#xff08;摄像头截图、照相&#xff…

实现区域截图功能

利用QQ或微信自带的截图功能实现区域截图。 在腾讯安装目录下找到PrScrn.dll&#xff0c;并将它放在需要的位置&#xff0c; 将D:/PrScrn.dll修改为你的目录。 如果在maya里面直接使用该代码 import os,subprocess from PySide2.QtWidgets import QApplication clipboard …

小米手机怎么截屏?小米手机区域截屏

小米手机怎么截屏&#xff1f;手机的截屏其实都是差不多的&#xff0c;基本上都是三指向下滑动而达到截屏效果的&#xff0c;但基本都是全屏截图。小米手机区域截屏怎么做&#xff1f;如果想要做到任意位置的那种区域块截屏的话&#xff0c;该怎么做&#xff1f;下面就来看看吧…

浏览器截图方法(长截图、node截图、指定区域截图)

1.打开需要截屏的页面&#xff0c;按键盘上的F2&#xff08;或者CtrlShiftI&#xff09;打开浏览器控制台 2.CtrlshiftP进入搜索框&#xff0c;输入“screen”: 这里有四种截图模式&#xff0c;点击需要的截图方式即可截取图片。

Windows关闭指定端口命令

假设要关闭端口号为3003&#xff0c;使用下面的命令&#xff0c;查出此端口号对应的PID netstat -ano|findstr 3003 上图红框内的 22876 就是3003端口对应的PID&#xff0c;再使用下面的命令就可以关闭这个端口了 taskkill /PID 22876 /F

Linux关闭端口

netstat -anp | grep xxx //查看端口是否被占用kill -9 10762 //即可关闭端口