八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击。共有几种摆法?

基础知识:

国际象棋里,棋盘为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语言 超详细 思路 基础的更多相关文章

  1. java实现八皇后问题(递归和循环两种方式)

    循环方式: package EightQueens;   public class EightQueensNotRecursive { private static final boolean AVA ...

  2. 八皇后非递归(仅使用一个数组且可扩展为N皇后问题)

    </pre><pre name="code" class="cpp">/* Theme:八皇后(非递归) Coder:秒针的声音 Tim ...

  3. 八皇后问题 --- 递归解法 --- java代码

    八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上.八皇后 ...

  4. 零基础入门C语言超详细的字符串详解

    本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, ...

  5. 超详细“零”基础kafka入门篇

    1.认识kafka 1.1 kafka简介 Kafka 是一个分布式流媒体平台 kafka官网:http://kafka.apache.org/ (1)流媒体平台有三个关键功能: 发布和订阅记录流,类 ...

  6. (企业面试部分)超详细思路讲解SQL语句的查询实现,及数据的创建。

    企业面试部分详细的SQL问题,思路讲解 第一步:创建数据库表,及插入数据信息 --Student(S#,Sname,Sage,Ssex) 学生表 CREATE TABLE student( sno ) ...

  7. Swift超详细的基础语法-结构体,结构体构造器,定义成员方法, 值类型, 扩充函数

    知识点 基本概念 结构体的基本使用 结构体构造器(构造函数/构造方法) 结构体扩充函数(方法), 又称成员方法 结构体是值类型 1. 基本概念 1.1 概念介绍 结构体(struct)是由一系列具有相 ...

  8. 超详细思路讲解SQL语句的查询实现,及数据的创建。

    最近一直在看数据库方面的问题,总结了一下SQL语句,这是部分详细的SQL问题,思路讲解: 第一步:创建数据库表,及插入数据信息 --Student(S#,Sname,Sage,Ssex) 学生表 CR ...

  9. 超详细Java基础-多态

    茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 多态就是指程序中定义的引用变量所指向的具体类型和通过该 ...

随机推荐

  1. 单台主机上DB2 10.5和arcgis 10.4 空间数据库配置

    该篇文章重点参考arcgis官网说明:http://enterprise.arcgis.com/zh-cn/server/10.4/publish-services/linux/register-db ...

  2. GUI常用对话框3

    %进度条 %waitbar h=waitbar(,'实例'); get(h); %获得进度条的子对象 get(get(h,'Children')) ha=get(h,'Children'); %获得坐 ...

  3. SQL表分区之一

    一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆分为多个小文件,还可以把这些小文件放在不同的磁盘下由 ...

  4. 自学java第六周的总结

    在这个星期里,我主要将以前看过的复习了一遍,并且阅读并做了相关的题. 下个星期继续努力.

  5. jboss的使用和安装

    1. 安装 1.1.软件安装 首先要安装JDK(仅仅安装JRE是不行的,因为JSP页面需要编译),最新的正式版是JDK1.4.2.然后把JBoss的压缩包解压到一个目录下,目录名一般是"Jb ...

  6. ltp-ddt的makefile结构

    顶层makefile COMMON_TARGETS        := pan utils COMMON_TARGETS    += tools testcases/ddt COMMON_TARGET ...

  7. 网上搜到的权限系统demo

    网上搜到的权限系统demo http://www.sojson.com/shiro

  8. FJOI2019游记

    应该是.....尽力了吧 day0:下午到酒店,晚上魔兽(with lyc)+雀魂.心里也清楚,今年只是来观光的. day1:上午暴力打完走人.下午和晚上魔兽+雀魂+300. day2:暴力打到一半拉 ...

  9. golang中tcp socket粘包问题和处理

    转自:http://www.01happy.com/golang-tcp-socket-adhere/ 在用golang开发人工客服系统的时候碰到了粘包问题,那么什么是粘包呢?例如我们和客户端约定数据 ...

  10. openstack cloud init set password

    设置代理和password #!/bin/bash cd /home/ubuntu wget otcloud-gateway.bj.intel.com/script.tar.gz ]; then cu ...