八皇后问题(递归回溯算法详解+C代码)

C语言:八皇后问题----回溯算法 【问题引入】 在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语言可以编程解决此问题。 【问题分析】 本题将要用到的是一种回溯的思想,为了更方便解释,先来看一道四皇后问题,也就是在4X4的棋盘上放四个. 阅读详情

       为了理解“递归回溯”的思想,我们不妨先将4位皇后打入冷宫,留下剩下的4位安排进4x4的格子中且不能互相打架,有多少种安排方法呢?现在我们把第一个皇后放在第一个格子,被涂黑的地方是不能放皇后的:

12

       第二行的皇后只能放在第三格或第四格,比如我们放在第三格:

放第二个皇后
       这样一来前面两位皇后已经把第三行全部锁死了,第三位皇后无论放在第三行的哪里都难逃被吃掉的厄运。于是在第一个皇后位于第一格,第二个皇后位于第三格的情况下此问题无解。所以我们只能返回上一步,来给2号皇后换个位置:
给第二个皇后换位置
       此时,第三个皇后只有一个位置可选。当第三个皇后占据第三行蓝色空位时,第四行皇后无路可走,于是发生错误,则返回上层调整3号皇后,而3号皇后也别无可去,继续返回上层调整2号皇后,而2号皇后已然无路可去,则再继续返回上层调整1号皇后,于是1号皇后往后移一格位置如下,再继续往下安排:
回溯重新安排一号皇后
核心代码如下:

void EightQueen( int row )
{
	int col;
	if( row>7 )                       //如果遍历完八行都找到放置皇后的位置则打印
	{
		Print();                       //打印八皇后的解 
		count++;
		return ;
		
	}

	for( col=0; col < 8; col++ )        //回溯,递归
	{
		if( notDanger( row, col ) )    // 判断是否危险
		{
			chess[row][col]=1;
			EightQueen(row+1);
			
			chess[row][col]=0;           //清零,以免回溯时出现脏数据
		}
	}
}

我们来重点看一下这段代码:

       第一次进来,row=0,意思是要在第一行摆皇后,只要传进来的row参数不是8,表明还没出结果,就都不会走if里面的return,那么就进入到for循环里面,col从0开始,即第一列。此时第一行第一列肯定合乎要求(即notDanger方法肯定通过),能放下皇后,因为还没有任何其他皇后来干扰。

       关键是notDanger方法通过了之后,在if里面又会调用一下自己(即递归),row加了1,表示摆第二行的皇后了。第二行的皇后在走for循环的时候,分两种情况,第一种情况:for循环没走到头时就有通过notDanger方法的了,那么这样就顺理成章地往下走再调用一下自己(即再往下递归),row再加1(即摆第三行的皇后了,以此类推)。第二种情况:for循环走到头了都没有通过notDanger方法的,说明第二行根本一个皇后都摆不了,也触发不了递归,下面的第三行等等后面的就更不用提了,此时控制第一行皇后位置的for循环col加1,即第一行的皇后往后移一格,即摆在第一行第二列的位置上,然后再往下走,重复上述逻辑。

       注意,一定要添加清零的代码,它只有在皇后摆不下去的时候会执行清0的动作(避免脏数据干扰),如果皇后摆放很顺利的话从头到尾是不会走这个请0的动作的,因为已经提前走if里面的return方法结束了。

       总之,这段核心代码很绕,原理一定要想通,想个十几二十遍差不多就能理解其中的原理了,递归回溯的思想也就不言而喻了。八皇后问题一共有92种情况

完整代码如下:

#include <stdio.h>

int count = 0;
int chess[8][8]={0};

int notDanger( int row, int col )
{
	int i,k;
	// 判断列方向
	for( i=0; i < 8; i++ )
	{
		if( chess[i][col]==1 )
		{
			return 0;
		}
	}
	// 判断左对角线 
	for( i=row, k=col; i>=0 && k>=0; i--, k-- )
	{
		if(chess[i][k]==1  )
		{
			return 0;
		}
	}
	// 判断右对角线 
	for( i=row, k=col; i>=0 && k<8; i--, k++ )
	{
		if(chess[i][k]==1  )
		{
			return 0;
		}
	}
	return 1;
}

void Print()          //打印结果 
{
	int row,col;
	printf("第 %d 种\n", count+1);
		for( row=0; row < 8; row++ )
		{
			for( col=0; col< 8; col++ )
			{
				if(chess[row][col]==1)        //皇后用‘0’表示
				{
					printf("0 ");
				}
				else
				{
					printf("# ");
				}
			}
			printf("\n");
		}
		printf("\n");
}

void EightQueen( int row )
{
	int col;
	if( row>7 )                       //如果遍历完八行都找到放置皇后的位置则打印
	{
		Print();                       //打印八皇后的解 
		count++;
		return ;
		
	}

	for( col=0; col < 8; col++ )        //回溯,递归
	{
		if( notDanger( row, col ) )    // 判断是否危险
		{
			chess[row][col]=1;
			EightQueen(row+1);
			
			chess[row][col]=0;           //清零,以免回溯时出现脏数据
		}
	}
}

int main()
{
	EightQueen(0);        
	printf("总共有 %d 种解决方法!\n\n", count);
	return 0;
}
数据结构与算法 — 八皇后问题(回溯算法) 问题描述 在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 假设上图中红点为一个皇后的位置,那么他的同行,列,斜线上都不能再放置其他皇后(也就是红线覆盖的位置) 此图为八皇后问题的其中一种解法,目前已经有人用图论的方法解出92种结果。 思路分析 一、如何实现 这就和我们人做这种题的时候一样,所有放置皇后的过程都是一行一行来的,首先将第一行的皇后放在第一个位置,然后再看第二行。最开始也是将第二行的皇后放在第二行的第一个位置,发现冲突 阅读详情

相关推荐

八皇后问题c语言算法

八皇后问题c语言算法

Maskwang 7008

八皇后问题4种c语言算法

八皇后问题 1.递归回溯法 B站懒猫老师讲的(我在这里学的) 八皇后问题的递归回溯算法思路:从第一行开始当某一行皇后位置不与前面所有皇后位置冲突那么记录该行皇后位置并调用递归函数进入下一行,摆放下一个皇后,逐个位置摆放,若该行所有位置都被其他皇后占领,那么就回溯到上一行重新摆放上一行皇后直至所有皇后都不冲突那么记录一次方法然后回溯寻找其他摆放方法。 冲突算法思路:一个8*8的棋盘每一个位置若用其行号加上其列号我们可以得到下图,由图可知在同一条上对角线的数值都相同,因此我们可以利用该规律设计判断上对角线是否冲

yunProgrammer的博客 1万+

回溯法求解八皇后问题

用回溯法求解八皇后问题

m0_65281955的博客 1925

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

前言: 各位和我一样的刚学完递归的小白们,是不是突然遇见了一个大BOSS,八皇后问题!!把自信的说着“老子递归学好了!”的你一棒子打回了出生点,就像你刚玩只狼遇到的那个大胖子,刚玩原神遇到的雪山。今天,我就和大家一起学习一下这个著名的八皇后问题。

c0re的博客 2万+

八皇后问题(C语言/C++)超详细讲解/由浅入深---深入八皇后问题

在计算机科学中,八皇后问题是一个经典的回溯算法问题。这个问题的目标是找出一种在8x8国际象棋棋盘上放置八个皇后的方法,使得没有任何两个皇后能够互相攻击。换句话说,每一行、每一列以及对角线上只能有一个皇后。想象一下,你是一个程序员,而棋盘是你的代码,皇后是你的变量。每个皇后(变量)都必须在自己的行上,不能与任何其他皇后(变量)冲突。你的任务就是找到一种方法,让这八个皇后(变量)在棋盘(代码)上和谐共存。首先,我们需要理解回溯算法。回溯算法是一种通过探索所有可能的选择和取消无效的选择来解决问题的算法。

宇宙超粒终端控制中心的博客 2131

[回溯法]八皇后问题的递归与非递归算法

八皇后的问题非常有名,初次理解可能稍有难度,不过多看书,看博客和代码,几遍下来,也基本清晰。首先不用想初始的情况,先假设前面已经排列好了几个皇后,即将排列下一个皇后。依次遍历八个位置,然后与之前的进行判断这个位置是否可行,如可行则进行下一个皇后,否则则移动位置继续判断。很简单。但是有两个个问题:1、不全,某个位置有八种方法排列,你只用了一种,当然你可以每个位置遍历,但太耗时,回溯法可以解决很大的一部

欲买桂花同载酒,终不似,少年游。 3931

利用递归求八皇后问题

八皇后问题是学习数据结构里很经典的一个问题,在8*8的棋盘里,摆放8个皇后,使其两两之间不会形成威胁! 计算目的: 1、遍历并输出每一种结果; 2、求得有多少种解法。 利用回溯算法计算把皇后问题是比较简单的! 我利用递归,就是为了求解!就是为了更深刻的了解递归! 进入代码,我会将代码做详细的注释,方便需要的同学去学习: 由main开始: #includ

Ben的专栏 1393

搜索与回溯算法之八皇后问题

搜索与回溯算法之八皇后问题 问题 要在国际象棋棋盘中放八个皇后,使任意两个皇后都不能互相吃。(提示:皇后能吃同一行、同一列、同一对角线的任意棋子。) 放置第i个(行)皇后的算法为: int search(i);  {    int j;    for (第i个皇后的位置j=1;j<=8;j++ ) //在本行的8列中去试    if (本行本列允许放置皇后)     {      放置第i个皇后; 对放置皇后的位置进行标记;      if (i==8) 输出

wmoxie的博客 1707

【递归与回溯算法】汉诺塔与八皇后问题详解

本文对递归与回溯算法的常见应用题:汉诺塔问题与八皇后问题进行了详细的讲解,并用代码实现验证。

黄小黄的博客 3667

C语言回溯法递归求解八皇后问题

Problem E 8皇后问题 时限:1000ms 内存限制:10000K 总时限:3000ms 描述: 输出8皇后问题所有结果。 输入: 没有输入。 输出: 每个结果第一行是No n:的形式,n表示输出的是第几个结果;下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格。不同的结果中,先输出第一个皇后位置靠前的结果;第一个皇后位置相同,先输出第二个皇后位置靠

geshengtong的博客 2384

C语言 八皇后问题 用递归回溯思想

八皇后问题: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 1、 ...

yiwen0313的博客 574

算法:递归与回溯算法解决八皇后问题

算法:递归与回溯算法解决八皇后问题什么是回溯算法如何用递归实现回溯算法(八皇后问题)八皇后问题的要求基本思想代码实现完整代码实现八皇后问题的完整代码 什么是回溯算法 在没有其他算法的加持下时,回溯算法简单来说,就是不断试错的过程。通过不断向下一个节点枚举寻找满足条件的答案,当无法寻找到时,则返回至上一个节点,然后继续向下枚举。 这句话可能看起来有点抽象,我们用一个图来演示一下。 这是一张A村到E村的地图。假设你从起点A出发到终点E(不是E1),在不知道路怎么走且时间、精力充足的情况下,你会选择一条条路走过去

ninelie's blog 1445

避坑指南:SpringBoot对接拉卡拉支付常见问题与解决方案(含SDK 1.0.6配置技巧)

本文是一份SpringBoot项目对接拉卡拉支付的实战避坑指南。针对SDK 1.0.6版本,详细剖析了从依赖管理、多环境配置、SDK初始化到支付请求构建、回调验签及生产监控的全流程常见问题,并提供了经过验证的解决方案与配置技巧,旨在帮助开发者高效、稳定地集成支付功能。

k5l6m的博客 327

算法设计 || 实验四 回溯算法-八皇后问题(纯手敲保姆级详细讲解+小白适用+头歌解析)

算法设计 || 实验四 回溯算法-八皇后问题(纯手敲保姆级详细讲解+小白适用+头歌解析)

Molly 的博客 5159

51单片机学习(5)-----蜂鸣器的介绍与使用

蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计 算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定 时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。1.半导体三极管也称为晶体三极管,可以说它是电子电路中最重要的器件。三极管顾名思义具有三个电极。二极管是由一个PN结构成的,而三极管由两个PN结构成,共用的一个电极成为三极管的基极(用字母b表示)。其他的两个电极成为集电极(用字母c表示)和发射极(用字母e表示)。

2302_80260350的博客 1万+

ARS408毫米波雷达数据解析避坑指南:从硬件连接到Python处理

本文提供了ARS408毫米波雷达从硬件连接到Python数据处理的完整实战指南。针对串口通信不稳定、数据解析错误等常见问题,详细解析了硬件连接方案选择、串口数据高效读取策略、二进制协议解析的位操作技巧,并给出了坐标转换、目标跟踪及实时可视化的代码实现,帮助开发者快速搭建稳定的雷达数据处理流水线。

weixin_29091105的博客 145

C++回溯算法与八皇后问题

今天想写一篇有关回溯法的问题,但是不知道开头应该介绍些什么东西。所以简单粗暴一点,直接上问题。一种经典的回溯算法就是八皇后问题,何为八皇后问题呢? 八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。 ——引自维基百科 为了更好的理解,上一张图: 图中画×的是满足条件的,画〇则不满足,因为有两个在同一条直线上。那么问题来了

WJ_SHI的博客 1797

S32K324 Stack异常分析及解决方案

在项目开发过程中,在一次软件变更时,调整了task优先级之后导致应用层软件中的float数据经常性的变为NAN,导致应用层功能失效。本文记录下这个bug的分析及解决过程。该问题排查了好几天,最开始正向排查不出来,差点放弃了,ETAS OS也没有人支持,只能换一种思路,通过反向推,最终定位到问题,能完美解决,还是很欣慰的。遇到问题不可怕,Bug一直都会有,主要是在解决问题中的思路和方法,不断总结积累,总会越来越好的!

赞的博客 587

回溯法(八皇后问题)及C语言实现

       回溯法,又被称为“试探法”。解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯法。 回溯VS递归         很多人认为回溯和递归是一样的,其实不然。在回溯法中可以看到有递归的身影,但是两者是有区别的。         回溯法从问题本身出发,寻找可能实现的所有情况...

yuer_xiao的博客 8万+

【毕设全程指导】基于YOLOv8的包装商品检测与可视化系统(SKU110K实战)

本文介绍了一个基于YOLOv8的包装商品检测与可视化系统毕业设计方案。项目采用SKU110K数据集,通过CSV转TXT格式转换适配YOLO模型训练,包含详细的环境搭建、模型配置和训练流程。系统实现了包装商品的自动化检测,并开发了Tkinter可视化界面进行交互式检测展示。该方案结合产业应用需求与技术深度,既具备实用价值,又能充分展示学生的技术能力,适合作为计算机视觉相关专业的毕业设计选题。整个项目从数据准备到界面开发完整覆盖,帮助学生系统掌握目标检测项目的完整实现流程。

LXY_LOVE36的博客 139

华为OD机试 - 停车场费用统计 - HashSet(Python/JS/C/C++ 双机位C卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。停车场统计当日总收费,包月的车不统计,不包月的车半个小时收一块钱,不满半小时不收费,如果超过半小时,零头不满半小时按半小时算,每天11:30-13:30时间段不收费,如果一辆车停车时间超过8小时后不收费。现提供停车场进出车辆的统计信息,需要你来计

学Java,找哪吒 234

C语言的回溯算法

递归函数的参数通常包括当前解的状态、当前解的深度、已选择的元素集合等。```cvoid backtrack(当前状态, 当前深度, 已选择元素集合) {// 判断是否满足结束条件if (满足条件) {// 记录当前解return;// 遍历选择for (每个可选元素) {// 做选择选择当前元素;// 递归调用backtrack(更新后的状态, 当前深度 + 1, 更新后的元素集合);// 撤销选择撤销当前元素;```

2501_91024662的博客 1149

使用MATLAB和Simulink来设计并仿真一个智能家居火灾报警系统

智能家居火灾报警系统旨在通过烟雾传感器、温度传感器等设备监测家庭环境,一旦检测到异常情况(如烟雾或温度骤升),立即触发警报并采取相应措施。在这个教程中,我们将使用MATLAB和Simulink来设计并仿真一个智能家居火灾报警系统,包括数据采集、处理以及响应机制。

amy_mhd的博客 160

回溯法(八皇后问题)及C语言实现

回溯法 回溯法,又被称为“试探法”。解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯法。 例如,在解决列举集合 {1,2,3} 中所有子集的问题中,就可以使用回溯法。从集合的开头元素开始,对每个元素都有两种选择:取还是舍。当确定了一个元素的取舍之后,再进行下一个元素,直到集合...

莫影 is Joker 4937

华为OD机试真题 新系统 2026-04-26 Python&JS 实现【最大化游戏试玩资格分发】

新研发了一台游戏设备可以面向用户接受试玩。现有 n 个试玩申请,每个试玩有开始时间和结束时间。作为协调员,为了能让更多人体验到游戏,你需要对试玩申请进行选择,使得:

MISAYAONE的博客 276

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: 数据结构和算法绪论
下一篇: BF算法详解
苍之羽
博客等级 码龄8年 514粉丝 58原创
评论 28
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值