八皇后问题 递归实现 C语言 超详细 思路 基础
八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击。共有几种摆法?
基础知识:
国际象棋里,棋盘为8X8格。
皇后每步可以沿直线、斜线 走任意格。
思路:
1.想把8个皇后放进去,肯定最终每行只有一个皇后,每列只有一个皇后。
2.设个二维数组chess [ i ] [ j ] 模拟棋盘,cas存放摆法。i j 是表示i行j列:
写一个用于递归的函数,思路如下
3.从上往下一行行的放皇后,放下一行时从最左边(第0列)放起,如果不能放就往右挪一格再试。注意判断右边有没有越界出棋盘。
4.写一个函数专门判断当前位置能不能放,只需要判断该位置的横、竖、两对角线,这四条线上有没有其他皇后即可。命名为check。
5.如果把最后一行放完了,那就统计上这个摆法,cas++。摆完最后一行不能继续判断下一行了。
6.放完一种情况,还要探究其他情况,可以把现在放好的皇后“拿走”,然后再试探 之前没试探过的棋盘格。
7.拿走皇后操作可以和不能放皇后的操作用同样的代码实现:
如果这个位置不能放,要把它置零,表示没有皇后。
如果这位置能放,那就放皇后(置1)。等一种情况讨论完,还得把它拿开,“拿开”也是置零的操作。
所以应该想办法排列上述代码,保证已经把摆出的情况记录下来,之后执行“拿开皇后”代码。
下面是递归函数部分:
void queen(int i,int j){
if(j>=line){ //如果右侧越界
return ;
} if(check(i,j)==1){//如果能放
chess[i][j]=1;//放皇后
if(i==line-1){//如果是最后一行,记录情况
cas++;
}
else{
queen(i+1,0);//不是最后一行就分析下一行
}
}//下面这两句是最精彩的chess[i][j]=0;//如果此位置不能放,就置空(0),判断旁边的格子。//如果此位置能放,走到这里就意味着上面的代码全部执行了,把皇后拿走(置零),再讨论其他情况,拿旁边位置试探。
queen(i,j+1);
}
然后开始写判断函数check。需要判断的是8个方向,把它看成4条直线考虑。对于所在的横行,竖列,直接用for循环判断。接下来考虑对角线(红色)。
这样可以看出来,要判断的对角线是每个象限的平分线,每次 i ,j 的变化量是相等的,只是符号有差异。横纵坐标变化量的范围是-8~8,当对角线走到边框时停止判断。
为什么是-8到8呢?因为咱们没必要确定对角线的精确范围,上图是最理想的对角线,但是因为目标位置不同,对角线范围也不同,每次计算两端点是不可取的。
直接按最长对角线划:
核心代码:
for(k=-line;k<=line;k++){//两对角线
if(i+k>=0&&i+k<line&&j+k>=0&&j+k<line)//从左上到右下对角线,如果在棋盘格里
if(chess[i+k][j+k]==1) return 0; if(i-k>=0&&i-k<line&&j+k>=0&&j+k<line)//从左下到右上对角线,如果在棋盘格里
if(chess[i-k][j+k]==1) return 0;
}
这个判断函数不重要,你写的函数达到目的就行。
注意一点,此函数只能设计成判断功能,不可以改变棋盘格的填充。
我刚开始觉得,当放置完上一个皇后,直接把这皇后所在的横纵斜方向全部填充一个数字,列为‘‘禁地’’,下一皇后放置时只要看待放入位置是否是“禁地”即可。但这么做是错的,因为不是把棋盘格填好一次就ok了,摆好一次后还需要把最后放的棋子拿开,探讨其他情况。如果划分禁地后,拿走皇后还得把禁地复原了,很麻烦的说。。而且代码量也不节省,就这么判断就行。
代码块的思路讲完,下面是完整代码。运行结果:92.
你写的程序也要保证这个结果。
#include<stdio.h>
#define line 8
void queen(int i,int j);
int check(int i,int j);
int chess[line][line];
int cas=0;
int xx,yy;
int main(){
queen(0,0);
printf("%d\n",cas);
return 0;
} void queen(int i,int j){
if(j>=line){
return ;
} if(check(i,j)==1){//如果能放
chess[i][j]=1;//放皇后
if(i==line-1){//如果是最后一行,记录情况
cas++;/*下面是输出每种棋盘结果,供测试for (xx=0;xx<8;xx++) for(yy=0;yy<8;yy++){ printf("%d",chess[xx][yy]); if(yy==7) printf("\n"); } printf("\n"); 上面是输出结果*/ }
else{
queen(i+1,0);//不是最后一行就分析下一行
}
}
chess[i][j]=0;//如果此位置不能放,就置空(0),判断旁边的格子。
//如果此位置能放,走到这里就意味着上面的代码全部执行了,把皇后拿走(置零),再讨论其他情况,拿旁边位置试探。
queen(i,j+1);
} int check(int i,int j){
int k; for(k=0;k<line;k++){
if(chess[i][k]==1) return 0;//0=不能放
}
for(k=0;k<line;k++){
if(chess[k][j]==1) return 0;
}
for(k=-line;k<=line;k++){//两对角线
if(i+k>=0&&i+k<line&&j+k>=0&&j+k<line)//从左上到右下对角线
if(chess[i+k][j+k]==1) return 0; if(i-k>=0&&i-k<line&&j+k>=0&&j+k<line)//从左下到右上对角线
if(chess[i-k][j+k]==1) return 0;
}
return 1;
}
八皇后问题 递归实现 C语言 超详细 思路 基础的更多相关文章
- java实现八皇后问题(递归和循环两种方式)
循环方式: package EightQueens; public class EightQueensNotRecursive { private static final boolean AVA ...
- 八皇后非递归(仅使用一个数组且可扩展为N皇后问题)
</pre><pre name="code" class="cpp">/* Theme:八皇后(非递归) Coder:秒针的声音 Tim ...
- 八皇后问题 --- 递归解法 --- java代码
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上.八皇后 ...
- 零基础入门C语言超详细的字符串详解
本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, ...
- 超详细“零”基础kafka入门篇
1.认识kafka 1.1 kafka简介 Kafka 是一个分布式流媒体平台 kafka官网:http://kafka.apache.org/ (1)流媒体平台有三个关键功能: 发布和订阅记录流,类 ...
- (企业面试部分)超详细思路讲解SQL语句的查询实现,及数据的创建。
企业面试部分详细的SQL问题,思路讲解 第一步:创建数据库表,及插入数据信息 --Student(S#,Sname,Sage,Ssex) 学生表 CREATE TABLE student( sno ) ...
- Swift超详细的基础语法-结构体,结构体构造器,定义成员方法, 值类型, 扩充函数
知识点 基本概念 结构体的基本使用 结构体构造器(构造函数/构造方法) 结构体扩充函数(方法), 又称成员方法 结构体是值类型 1. 基本概念 1.1 概念介绍 结构体(struct)是由一系列具有相 ...
- 超详细思路讲解SQL语句的查询实现,及数据的创建。
最近一直在看数据库方面的问题,总结了一下SQL语句,这是部分详细的SQL问题,思路讲解: 第一步:创建数据库表,及插入数据信息 --Student(S#,Sname,Sage,Ssex) 学生表 CR ...
- 超详细Java基础-多态
茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 多态就是指程序中定义的引用变量所指向的具体类型和通过该 ...
随机推荐
- strace跟踪多进程与内核的交互
1.ptrace的说明 ptrace原型: #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_t ...
- 大数据自学2-Hue集成环境中使用Sqoop组件从Sql Server导数据到Hive/HDFS
安装完CDH后,发现里面的东东实在是太多了,对于一个初学大数据的来说就犹如刘姥姥进了大观园,很新奇,这些东东每个单拿出来都够喝一壶的. 接来来就是一步一步地学习了,先大致学习了每个模组大致做什么用的, ...
- 全球最大的3D数据集公开了!标记好的10800张全景图
Middlebury数据集 http://vision.middlebury.edu/stereo/data/ KITTI数据集简介与使用 https://blog.csdn.net/solomon1 ...
- Vim常用命令:移动 跳转 到 文档开头或末尾
gg:命令将光标移动到文档开头 G:命令将光标移动到文档末尾 vi编辑器中在命令行模式下输入G可以直接跳转到页面的底部 在命令行模式下输入1G可以跳转到页面的头部位置 更多在vi中移动编辑位置的命令说 ...
- navicat mysql导出数据 批量插入的形式
这里介绍的是mysql 相同服务器类型数据传输的高级设置 选中数据库后右键“ 转储SQL文件”默认导出的记录格式是一条条的,采用的是”完整插入语句”,格式如下 '); '); '); 这种格式保证了兼 ...
- Golang匿名函数
概念所谓匿名函数,就是没有名字的函数匿名函数的两种使用方式一.在定义匿名函数的时候就可以直接使用(这种方式只使用一次) package main import ( "fmt" ) ...
- Vue 基础精讲
Vue 基础精讲 Vue 官方文档:https://cn.vuejs.org/v2/guide/ VUE 实例 每个组件都是一个 vue 的实例. 一个 vue 项目是由实例组成的. vue 实例上有 ...
- Hibernate properties文件
###################### ### Query Language ### ###################### ## define query language consta ...
- k8s build new API
apiserver-builder git hub api conventions storage api arch step by step, we can follow it. api con ...
- applyColorMap()研究(如果我对现有的colormap不满意,那么如何具体来做)
cv::applyColorMap()能够实现预定义的伪彩色,这个是众所周知的事情. 并且和matlab提供的很相近 除了这些预置的变换,如果我想实现新的变换,需要做LUT变换 cv::Mat ...