n皇后问题的子集树求解与排列树求解

回溯算法:子集树和排列树 本文参考了其他博文,参考出附上了原文链接。侵权联系我删除! 1.算法介绍 回溯算法是一个既带有系统性,又带有跳跃性的搜索算法: 系统性:它在包含问题的所有解空间树中,按照深度优先策略,从根节点出发搜索解空间树 跳跃性:算法搜索至解空间树的任一节点时,判断该节点为根的子树是否包含问题的解,如果肯定不包含,则跳过搜索以该节点为根的子树的搜索,逐层向其祖先节点回溯。否则进入该子树,继续按深度优先... 阅读详情

在n×n棋盘上放彼此不受攻击的n个皇后。
按国际象棋规则,皇后可攻击同行、同列、同一斜线的棋子。

等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

 

可以用一个数组存储每行中的皇后的纵坐标,例如n=8时,X=(4,6,8,2,7,1,3,5)表示第一行的皇后的横坐标为4,

第二行的皇后的横坐标为6,......

比较常用的一种求解办法为通过子集树求解,约束条件为abs(k-j)!=abs(x[j]-x[k]) 并且 x[j]!=x[k]。

其实这个问题也可以描述为n个数字的排列问题,约束条件为abs(k-j)!=abs(x[j]-x[k]),这样该问题就可以用全排列的算法求解。

子集树求解的程序为:

#include <cstdio>
#include <cmath>
int x[20];
int n,count;
int Place(int k)
{
	int j;
	for(j=1;j<k;j++)
		if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
			return 0;
	return 1;
}
void Backtrack(int t)
{
	int i;
	if(t>n) 
	{
		for(i=1;i<=n;i++)
			printf("%d ",x[i]);
		printf("\n");
		count++;
	}
	else
	for(i=1;i<=n;i++) 
	{
		x[t]=i;
		if(Place(t))
			Backtrack(t+1);
    }
}
int main()
{
	printf("请输入n:");
	scanf("%d",&n);
	Backtrack(1);
	printf("共%d组答案\n",count);
	return 0;
}

排列树求解的程序为:

#include <cstdio>
#include <cmath>
int n,count;
int Place(int data[], int k)
{
	int j;
	for(j=1;j<k;j++)
		if(abs(k-j)==abs(data[j]-data[k]))
			return 0;
	return 1;
} 
void swap(int &x, int &y)
{
	int temp;
	temp=x;
	x=y;
	y=temp;
}

void perm(int data[], int k, int n)
{
	int i;
	if(k>n)
	{
		for(i=1;i<=n;i++)
			printf("%d ",data[i]);
		printf("\n");
		count++;
	}
	else
	{
		for(i=k;i<=n;i++)
		{
			swap(data[k],data[i]);
			if(k==1 || Place(data,k))
				perm(data,k+1,n);
			swap(data[i],data[k]);
		}
	}
}
int main()
{
	int i;
	int data[20];
	printf("请输入n:");
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		data[i]=i;
	perm(data,1,n);
	printf("共%d组答案\n",count);
	return 0;
}

 

 

 

3.2 回溯法—N皇后问题 1. 问题描述 在n×nn\times nn×n的棋盘上摆放nnn个皇后,使任意两个皇后都不能处于同一行、同一列或同一斜线上 2. 问题分析 下以求解4皇后问题为例,分析4皇后问题的排列树以及回溯过程: 搜索及回溯过程: 解空间树: 3. 算法设计 1. 算法思想 ①用数组x[]存放皇后的位置,x[k]表示第k个皇后放置的位置 ②先在第一行放置第1个皇后,然后依2、3、…、n的次序放置其他皇后,当第n个皇后放置好后产生要给可行解(为得到所有解,还需要继续试探第n个皇后的下一个位置) ③在试探第k(k 阅读详情

相关推荐

四类九种移位寄存器总结(循环(左、右、双向)移位寄存器、逻辑和算术移位寄存器、串并转换移位寄存器、线性反馈移位寄存器LFSR|verilog代码|Testbench|仿真结果)

移位寄存器有哪些分类呢? 按移位方向分类:①单向移位寄存器(包括左移、右移)②双向移位寄存器 按循环方式分类:①循环移位寄存器②非循环移位寄存器 按部位的不同分类:①逻辑移位寄存器②算术移位寄存器 按输入输出方式分类:①串入串出②串入并出③并入串出④并入并出

Loudrs的博客 1万+

N皇后问题

一、问题描述:   在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。输入:   给定棋盘的大小n (n ≤ 13) 输出:   输出有多少种放置方法。二、解题思路:    要解决N皇后问题,其实就是要解决好怎

x_i_y_u_e的专栏 3941

Type-C转DP1.4转C双向互传转接线方案

Type-C转DP双向互转方案的核心在于利用Type-C接口中的Alt Mode(交替模式)功能。通过利用Type-C接口的Alt Mode功能,该方案实现了Type-C接口与DP接口之间的双向互传,极大地丰富了用户的视觉体验。在选择Type-C转DP双向互转方案时,用户需要关注兼容性、性能需求、线缆长度和品牌等因素,以确保获得最佳的传输质量和使用体验。因此,Type-C转DP双向互转方案应运而生,旨在实现Type-C接口与DP接口之间的无缝连接,满足用户对高效能和高清晰度视频传输的需求。

m0_70875024的博客 4974

n皇后问题-c++ dfs

题目描述 在n×n 格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。 设计一个解 n 后问题的队列式分支限界法,计算在n´ n个方格上放置彼此不受攻击的n个皇后的一个放置方案。 输入格式: 1 个正整数n 输出格式: 输出计算出的彼此...

weixin_44546342的博客 1685

folium离线地图实战:从下载到部署的完整指南

本文提供了一份完整的folium离线地图实战指南。针对网络不稳定或内网环境下的地图应用需求,详细讲解了如何下载离线地图瓦片数据,并通过两种核心方法(直接替换URL与创建TileLayer)将其集成到folium中。文章还涵盖了部署优化、边界处理及资源本地化等关键步骤,帮助你构建完全脱离网络依赖的交互式地图应用。

weixin_29061041的博客 274

uniapp监听扫码枪键盘事件|无输入框式监听

一般的扫码枪通过USB或蓝牙连接手机或电脑,充当的是一个外接设备。当扫码后,扫码枪会自动识别内容,然后向连接的电脑或手机发送键盘事件keydown或keyup。

tcy9099的专栏 9748

N皇后问题(子集树、排列树回溯法)

> 这题既可以采用子集树也可用排列树 问题描述 解向量 可行性约束 限界约束 代码一:子集树解决 #include <iostream> using namespace std; int x[100]; //皇后的位置(i,x[i]),即x[i]表示皇后在i行的列位置 int n; //棋盘规格 int sum = 0; bool Place(int t) //实现限界约束判断 { for (int i = 1; i <t;i++)

qq_47299421的博客 4487

【常见开源库的二次开发】基于openssl的加密与解密——openssl认识与配置(一)

OpenSSL 是一个开源的软件库,它提供了一系列加密工具和协议,主要用于实现安全通信,如在网络上的数据传输。它支持多种加密算法,包括对称加密、非对称加密、散列函数、伪随机数生成器、数字签名、密钥交换以及证书管理等。

嵌入式技术开发 4160

子集树与排列树

一、子集树 当所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间称为子集树 现需打印序列(长度为n)的全部子集,将问题抽象转化为一棵二叉树. 一个序列的所有子集为2^n,即可看成具有2^n个叶节点的满二叉树,总结点个数为2^(n+1)-1. 需定义额外数组保存当前分支的打印信息(左分支置1,右分支置0) 每遍历完一条分支,打印当前分支序列 如上图:用数组arr=...

XD_fybdw的博客 1万+

win10解决IE浏览器安装不上的问题(卸载依然显示不能安装)

目前win10 系统不支持外部ie安装程序,所以必须用win10自带的应用来安装 一、错误的卸载的方式 在控制面板的当前安装的程序界面是看不到ie的,需要选择控制面板左上角的启用或关闭windows功能 将ie11前面的勾勾去掉 这种方法是很多网站上的误区,其实这并没有卸载成功ie只是把ie的功能关闭了,但是他还在你的电脑上。你可以理解为我们说的对文件夹执行的隐藏文件夹功能。那个隐藏的文件夹依...

清平乐的技术专栏 3万+

软件设计师---程序设计语言

软件设计师---程序设计语言

我从不打没有准备的仗! 2万+

回溯法拓展2 educoder

第1关:非递归实现皇后问题 任务描述 本关任务:在n×n格的棋盘上放置彼此不受攻击的 n 个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。用非递归算法解决该问题。 ...

qq_46675545的博客 2246

C/C++炫酷烟花①(完整代码)

C/C++实现炫酷烟花动画的完整代码。

AIGC 2万+

使用回溯法和排列树(降维和减枝)解决N皇后问题

上一篇博客使用回溯法和子集树(降维法)解决N皇后问题 运用了降维,极大的提高了计算效率。不过能不能再精益求精呢?~能的,还能继续优化。前面运用了排列树,对于4x4来说,子集规模为nn = 44 = 256。这里我们采用减枝进一步优化。 思路很简单,假如x[0] = 1,则x[1],x[2],x[3]就不可能在等于1。 x[0] = 1就代表皇后摆放在第一行的第2个位置。则后面2,3,4行就不可能摆...

Twilight blog 2833

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

回溯算法

一,回溯算法的基本思想 回溯法从根节点出发,以深度优先搜素整个解空间。这个根节点成为活节点,成为当前的扩展节点。在当前扩展节点处,搜索向纵深方向移至一个新节点,这个新节点成为新的活节点,并成为当前扩展节点。如果在当前扩展节点处不能再向纵深方向移动,则当前扩展节点就成为死节点。此时,应往回移动至最近一个活节点处,并使这个活节点成为当前扩展节点。回溯法以这种工作方式递归地在解空间中搜索,直至找到所要

个人技术博客 456

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

回溯法详解:N皇后问题从模板到剪枝与调试实战

在算法设计与分析中,搜索类问题常面临组合爆炸的挑战。回溯法是一种通过决策序列逐步构造解的系统搜索策略,其核心在于路径、选择列表与结束条件的组织,并利用剪枝提前终止无效分支,从而显著压缩搜索空间。与纯暴力枚举不同,回溯法在递归框架下边探索边验证约束,广泛应用于N皇后、全排列、组合、数独及作业调度等约束求解场景。理解状态空间树和剪枝原理,能够帮助开发者高效解决面试题与工程中的排程、路径搜索问题。本文以N皇后为主线,完整剖析从模板框架到状态标记、对称优化及调试陷阱的实战过程。

weixin_34072296的博客 238

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

算法设计与分析学习笔记(6)——排列树与子集树

常见的解空间结构 1.子集树 概述:子集树是使用回溯法解题时经常遇到的一种典型的解空间树。当所给的问题是从n个元素组成的集合S中找出满足某种性质的一个子集时,相应的解空间树称为子集树。此类问题解的形式为n元组(x1,x2…xn),分量xi(1,2,…n)表示第i个元素是否在要找的子集中。xi的取值为0或者1,xi=0 表示第i个元素不在要找的子集中;xi=1 表示第i个元素在要找的子集中。 树的根结点:初始状态 中间结点:某种情况下的中间状态 叶子结点:结束状态 分支:从一个状态过渡到另一个状态的行为 从

qq_45976312的博客 9631

算法设计与分析——分支限界法——n皇后问题

#include<iostream> #include<queue> #include<cmath> #include<vector> #include<fstream> #include<sstream> using namespace std; //定义一个节点类 struct Node{ int number; vector<int>x;//保存当前解 }; //定义一个Queen的类 class Q

qq_50675813的博客 6355

回溯法——N皇后问题与TSP问题

回溯法——N皇后问题与TSP问题 对于一般的问题而言,很多时候无法找到其最优子结构性质或者其不是一个最优化问题,这些问题都是NP的。我们无法采用像动态规划一样的技巧简化求出某个具体解的过程,唯一能做的就是蛮力遍历所有可能的解。在蛮力法的基础上,假如把求每个解的过程组织成一个树状结构,从根节点到叶节点的每次遍历就是一个可能解,那么就可以采用深搜+剪枝的方式来简化计算,在计算之前就知道某些解是不可行的,因此可以说回溯法是特殊情况下对蛮力法的优化。 问题: N后问题:在N×N的棋盘中放置N个皇后,使得任何两个皇后

qq_43513855的博客 1163

详解回溯法

文章目录回溯法概念适用条件解题步骤回溯法和DFS的区别常见题型素数环迭代递归 回溯法 references: 回溯算法 回溯算法 详细讲解回溯算法(一) 回溯法-素数环问题 素数环(java实现) 概念 回溯(backtracking)法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满...

LynnWonder 5160

回溯算法核心:排列树与子集树模型详解与实战优化

回溯算法是深度优先搜索(DFS)在解空间上的系统化应用,其核心思想是通过递归尝试所有可能的解,并在不满足条件时回退。该技术为解决组合优化和排列问题提供了通用框架,尤其在处理解空间呈指数或阶乘级增长时,展现出强大的问题建模能力。其技术价值在于将复杂的暴力搜索过程结构化,通过清晰的决策路径(选/不选、定序)实现高效遍历。在实际工程中,回溯算法广泛应用于解决全排列、组合选择、N皇后、0-1背包等经典问题。本文聚焦于回溯算法的两种核心抽象模型——排列树与子集树,深入解析其标准模板、剪枝优化和常见避坑指南,帮助开发者

weixin_30376509的博客 299

算法期末复习总结 || 回溯法(0/1背包、装载、n皇后)

回溯法 文章目录回溯法1. 回溯法的基本原理、解空间的概念以及算法框架(子集树、排列树)【基本原理】【解空间】【算法框架】1. 子集树2. 排列树2. 剪枝函数如何设计?回溯法相较于蛮力法的优势?3. 0/1背包问题4. 装载问题5. n皇后问题 1. 回溯法的基本原理、解空间的概念以及算法框架(子集树、排列树) 【基本原理】 回溯法实际上一个类似穷举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”(即回退),尝试别的路径。 回溯法搜索解空间时,通常采用两种策略【剪

一只羊驼没有毛的博客 1263

回溯算法基础---皇后问题,骑士游历,迷宫求解

回溯法(又叫试探法)是属于穷举的子集,对于许多的问题,当我们需要找到某些解集或者满足某种要求的最优解的时候,回溯法往往是很朴素和简单的一种算法。从数学的角度来说,比较适合一些组合数较大的问题,比如五子棋博弈算法,最短路径(最小代价)等,使用回溯算法往往会得到正确的答案,但是回溯算法由于是采用穷举的方式,所以运行时间一般是很大的,当然可以通过各种优化手段来降低,而许多的问题--------回溯法是最

Vurteon的专栏 5118

算法设计与分析案例代码总结(三):回溯法

回溯法 简单概述  回溯法(深度优先搜索),其实是蛮力搜索法的一种升级版本,它把问题的解空间转换为了图或者树的结构表示,然后使用深度优先策略进行遍历,遍历的过程寻找所有的最优解或可行解。  回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其...

zycode1561的博客 1792

回溯法--n皇后问题

经典的n皇后问题 回溯法有两个模板--子集树、排列树,他们有回溯法的共同特点:深度优先搜索,如果一条路走不通,再退回来(类似递归)

m0_56147044的博客 5416

N皇后问题(回溯算法解法)

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3464    Accepted Submission(s): 1599 Problem Description 在N*N的方格棋盘放置了N个皇后

hushhw的博客 7560
上一篇: 连续邮资问题
下一篇: 能显示层号的按层遍历二叉树
xifengcode
博客等级 码龄9年 529粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值