八皇后问题的解决完整文档
八皇后问题(经典算法-回溯法)
⼋皇后问题(经典算法-回溯法)
问题描述:
⼋皇后问题(eight queens problem)是⼗九世纪著名的数学家⾼斯于1850年提出的。问题是:在8×8的棋盘上摆放⼋个皇后,使其不能互相攻击。即任意两个皇后都不能处于同⼀⾏、同⼀列或同⼀斜线上。
可以把⼋皇后问题扩展到n皇后问题,即在n×n的棋盘上摆放n个皇后,使任意两个皇后都不能互相攻击。
思路:
使⽤回溯法依次假设皇后的位置,当第⼀个皇后确定后,寻找下⼀⾏的皇后位置,当满⾜左上、右上和正上⽅向⽆皇后,即矩阵中对应位置都为0,则可以确定皇后位置,依次判断下⼀⾏的皇后位置。当到达第8⾏时,说明⼋个皇后安置完毕。
代码如下:
#include<iostream>
using namespace std;
#define N 8
int a[N][N];
int count=0;
//判断是否可放
bool search(int r,int c)
{
int i,j;
//左上+正上
for(i=r,j=c; i>=0 && j>=0; i--,j--)
{
if(a[i][j] || a[i][c])
{
return false;
}
}
//右上
for(i=r,j=c; i>=0 && j<N; i--,j++)
{
if(a[i][j])
{
return false;
}
}
return true;
}
//输出
void print()
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
cout<<a[i][j]<<" ";
八皇后问题
八皇后问题
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
对于八皇后问题的实现,如果结合动态的图形演示,则可以使算法的描述更形象、更生动,使教学能产生良好的效果。下面是用Turbo C实现的八皇后问题的图形程序,能够演示全部的92组解。八皇后问题动态图形的实现,主要应解决以下两个问题。
(1)回溯算法的实现
(a)为解决这个问题,我们把棋盘的横坐标定为i,纵坐标定为j,i和j的取值范围是从1到8。当某个皇后占了位置(i,j)时,在这个位置的垂直方向、水平方向和斜线方向都不能再放其它皇后了。用语句实现,可定义如下三个整型数组:
a[8],b[15],c[24]。其中:
a[j-1]=1 第j列上无皇后
a[j-1]=0 第j列上有皇后
b[i+j-2]=1 (i,j)的对角线(左上至右下)无皇后
b[i+j-2]=0 (i,j)的对角线(左上至右下)有皇后
c[i-j+7]=1 (i,j)的对角线(右上至左下)无皇后
c[i-j+7]=0 (i,j)的对角线(右上至左下)有皇后
(b)为第i个皇后选择位置的算法如下:
for(j=1;j<=8;j++) /*第i个皇后在第j行*/
if ((i,j)位置为空))/*即相应的三个数组的对应元素值为1*/
八皇后问题递归算法
八皇后问题递归算法
八皇后问题是一个经典的数学问题,其目标是在一个8×8的棋盘上放置8个皇后,使得没有两个皇后位于同一行、同一列或同一斜线上。这个问题可以通过递归算法来求解,本文将详细介绍八皇后问题的递归算法及其实现过程。
我们需要定义一个函数来判断当前位置是否可以放置皇后。该函数的输入参数为当前行和当前列,输出为一个布尔值,表示该位置是否可以放置皇后。具体实现如下:
```
bool isSafe(int board[8][8], int row, int col)
{
int i, j;
// 检查当前列是否有其他皇后
for (i = 0; i < row; i++)
if (board[i][col])
return false;
// 检查左上方是否有其他皇后
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
if (board[i][j])
return false;
// 检查右上方是否有其他皇后
for (i = row, j = col; i >= 0 && j < 8; i--, j++)
if (board[i][j])
return false;
return true;
}
```
接下来,我们可以使用递归算法来解决八皇后问题。递归算法的思想是将问题分解为子问题,然后逐步解决子问题,最终得到原问题的解。具体的递归算法如下:
```
bool solveNQueens(int board[8][8], int row)
{
// 所有行都已经放置好了皇后,得到了一个解
八皇后问题
八皇后问题是一个古老而著名的问题,是回溯算法的典型 例题。该问题是十九世纪著名的数学家高斯1850年提出:在 8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任 意两个皇后都不能处于同一行、同一列或同一斜线上,问有 多少种摆法?八皇后在棋盘上分布的各种可能的数目非常大。 但是可以将一些明显不满足问题要求的格局排除掉,由于任 意两个皇后不可能同行,即每一行只能放置一个皇后,因此 将第i个皇后放置在第i行上。这样 在放置第i个皇后时,只要 考虑它与前i-1个皇后处于不同列和不同对角线位置上即可。
来自百度文库
一般算法
用 数组a、b、c分别用来标记冲突,a数组代表列冲突,从a[0]~a[7]代表第0列到第 7列,如果某列上已经有皇后,则为1,否则为0; 数组b代表主对角线冲突,为b[i-j+7],即从b[0]~b[14],如果某条主对角线上已经 有皇后,则为1,否则为0; 数组c代表从对角线冲突,为c[i+j],即从c[0]~c[14],如果某条从对角线上已经有皇 后,则为1,否则为0; 从第一行起 逐个放置皇后,每放置一个皇后依次对第1,2......8列进行试探,若当 前 试探的列位置是安全的,则将该行的列位置保存在栈中,然后继续在下一行寻 找安全位置,若当前试探的列位置不安全,则用下一列进行试探,当8列的位置试 探完毕都未能找到安全位置时,就退栈回溯到上一行,修改栈顶保存的皇后位置, 然后继续试探。
经典算法-(五)八皇后问题
经典算法-(五)⼋皇后问题
简介:
问题,是⼀个古⽼⽽著名的问题,是的典型案例。该问题是国际西洋棋棋⼿马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放⼋个皇后,使其不能互相攻击,即任意两个皇后都不能处于同⼀⾏、同⼀列或同⼀斜线上,问有多少种摆法。认为有76种⽅案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有⼈⽤图论的⽅法解出92种结果。计算机发明后,有多种计算机语⾔可以解决此问题。
问题描述:
⼋皇后问题是⼀个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置⼋个皇后,使得任何⼀个皇后都⽆法直接吃掉其他的皇后?为了达到此⽬的,任两个皇后都不能处于同⼀条横⾏、纵⾏或斜线上。⼋皇后问题可以推⼴为更⼀般的n皇后摆放问题:这时棋盘的⼤⼩变为n1×n1,⽽皇后个数也变成n2。⽽且仅当 n2 = 1 或 n1 ≥ 3 时问题有解。
java实现:
public class Queen{
//同栏是否有皇后,1表⽰有
private int[] column;
//右上⾄左下是否有皇后
private int[] rup;
//左上⾄右下是否有皇后
private int[] lup;
//解答
private int[] queen;
//解答编号
private int num;
public Queen(){
column=new int[8+1];
rup=new int[(2*8)+1];
lup=new int[(2*8)+1];
for(int i=1;i<=8;i++)
1213:八皇后问题
1213:⼋皇后问题【题⽬描述】
在国际象棋棋盘上放置⼋个皇后,要求每两个皇后之间不能直接吃掉对⽅。
【输⼊】
(⽆)
【输出】
按给定顺序和格式输出所有⼋皇后问题的解(见样例)。
【输⼊样例】
(⽆)
【输出样例】
No. 1
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
No. 2
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0
...以下省略
解题分析:关键在于斜线还有是否访问过,正斜与反斜⾓的特点
#include<bits/stdc++.h>
using namespace std;
int a[10001],b[10001],w[10001],m[10001],tot=0;
int print()
{
tot++;
cout<<"No. "<<tot<<endl;
for(int j=1;j<=8;++j)
{
for(int i=1;i<=8;++i)
if(j==a[i])cout<<1<<" ";
else cout<<0<<" ";
八皇后问题的解决方案
3
解决八皇后问题常用算法
3.1
枚举法解决八皇后问题
3.2
非递归回溯法解决八皇后问题
3.3
递归回溯法解决八皇后问题
3.0
பைடு நூலகம்
八皇后问题约束条件
a( i ) 1 2 3 4 5 6 7 8 a( 1) 2 0 -1 3 -2 4 -3 5 -4 6 -5 7 -6 8 -7 9
a( 2 ) a( 3 ) a( 4) a( 5 ) a( 6) a( 7 ) a( 8)
算法总结
3.3
递归回溯法解决八皇后问题
调用search(1) 行号r=形参
r>8
是 否 否 是
输出解
i<8 q(r)=i q(r)列符合放 置条件
是 否
返回0
i=i+1
调用search(r+1)
Private Function search(ByVal r As Integer) If (r > 8) Then printstr(q) Return 0 End If For i = 1 To 8 q(r) = i Dim OK% = 1 For j = 1 To r - 1 If q(r) = q(j) Or Math.Acos(r - j) = Math.Abs(q(r) - q(j)) Then OK = 0 Exit For End If Next If OK = 1 Then search(r + 1) Next Return 0 End Function
8皇后问题分析与解法
递归算法——八皇后问题
1、背景问题描述
八皇后问题是一个古老而著名的问题,该问题的目标是在8×8的国际象棋棋盘上放置八个皇后,使得任意两个皇后都不在同一行,或同一列或同一对角线上。如图1所示就是八皇后问题的一个解。
图1 八皇后问题的一个解
1854年在柏林的象棋杂志上不同的作者发表了40种不同的解。大数学家高斯认为有76种不同的方案。后来有人用图论的方法算出92种不同的解。
能否利用程序算出所有满足条件的解的数目呢?
2、抽象表示及存储
对于这种矩形排列的棋盘而言,用二维数组存储棋盘的状况是最容易想到的方法。可以设置一个8*8的二维数组,令有棋子的位置为1,无棋子的部分为0。
事实上,由于8个皇后中任意两个皇后都不在同一行,因此8个皇后只能各自占据一行。不妨认为8个皇后编号为0、1、……、7,它们各自占据棋盘的第1行、第2行、……、第8行。从而可以使用长度为8一维数组表示棋盘状态,数组元素的下标表示棋子所在行,数组元素的值表示各个棋子所在的列。
使用的存储方式不同,其采用的算法已有很大区别。
3、问题分析及算法设计
假定用二维数组A存储棋盘的情况,可以考虑下面两种思路。
思路一:不考虑任何限制的穷举法。
用8×8的二维数组存储棋盘,若在(i,j)处有子,则令A[i][j]=1,否则A[i][j]=0。于是8个棋子第1个有64种摆放方法,第2个有63种放法,……,第8个有57种放法,则所有摆放方法有64×63×62×…×57种。可以列举每一种摆法,而后考察每种方法是否符合条件。这个计算量非常大。
思路二:考虑经过优化的穷举法(二维数组方案)。
八皇后问题实验报告
软件工程上机报告
实验名称:八皇后问题图形界面求解
姓名:郭恂
学号:2011011435
班级:11级数学班
中国石油大学(北京)计算机科学与技术系
一、试验程序截图:
点击显示下一组解即可显示下一组解:
同样的,如果点击上一组解即可显示上一组解。
若在第1组解时点击显示上一组解会弹出报错提示框。
同样,若在第92组解点击显示下一组解也会弹出报错提示框:
二、程序代码
程序使用Java语言编写,编写环境为jdk1.6.0_18。使用编程开发环境eclipse.exe编写。
本程序创建了两个类,两个类在同一个工程中。其中Queen类的作用仅仅用来保存八皇后问题计算结果的数据,便于画图时使用。
本程序大概由两部分组成,第一部分是解八皇后问题,第二部分是画图。
程序源代码为:
类1:
public class Queen
{
public int[] x=new int[8];
public int[] y=new int[8];
public String name;
}
类2:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.JOptionPane;
public class bahuanghou extends JFrame implements ActionListener {
//JLabel[] l;
int number=0; //当前显示的解的编号
int sum=0; //所有解得数量
JLabel l2;
JButton b1,b2; //b1为显示下一组解得按钮,b2为显示上一组解得按钮。
皇后问题详细的解法
双重循环,任意两个皇
queen1( )盲目的枚举算法
{ int a[9];
用a[1]~a[8]存储x1~x8
后之间都必须检查。
check1(a[],n) {int i,j;
for (a[1]=1;a[1]<=8;a[1]++) for (a[2]=1;a[2]<=8;a[2]++)
for(i=2;i<=n;i++) for(j=1;j<=i-1;j++)
皇后的位置; 由于行号固定,可简单记为:(x1,x2,x3,x4,x5,x6,x7,x8); 问题的解空间:(x1,x2,x3,x4,x5,x6,x7,x8),1≤xi≤8(i=1,2,3, 4……,8),共88个状态; 约束条件:八个(1,x1),(2,x2) ,(3,x3),(4,x4) ,(5,x5), (6,x6) , (7,x7), (8,x8)不在同一行、同一列和同一对角线上。 原问题即:在解空间中寻找符合约束条件的解状态。
枚举得有个顺序,否则 轻则有漏的、重复的; 重则无法循环表示。
6
1.按什么顺序去查找所有的Leabharlann Baidu a.盲目的枚举算法
void main() {
int x[100]; for (x[1]=1;x[1]<=10;x[1]++) for (x[2]=1;x[2]<=10;x[2]++)
八皇后问题—经典回溯算法
⼋皇后问题—经典回溯算法
⼋皇后问题
⼋皇后问题,是⼀个古⽼⽽著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋⼿马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放⼋个皇后,使其不能互相攻击,即任意两个皇后都不能处于同⼀⾏、同⼀列或同⼀斜线上,问有多少种摆法。⾼斯认为有76种⽅案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有⼈⽤图论的⽅法解出92种结果。
回溯算法思想
回溯算法的基本思想是:从⼀条路往前⾛,能进则进,不能进则退回来,换⼀条路再试。⼋皇后问题就是回溯算法的典型,第⼀步按照顺序放⼀个皇后,然后第⼆步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第⼀个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了。回溯在迷宫搜索中使⽤很常见,就是这条路⾛不通,然后返回前⼀个路⼝,继续下⼀条路。回溯算法说⽩了就是穷举法。不过回溯算法使⽤剪枝函数,剪去⼀些不可能到达最终状态(即答案状态)的节点,从⽽减少状态空间树节点的⽣成。回溯法是⼀个既带有系统性⼜带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索⾄解空间树的任⼀结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该结点为根的⼦树的系统搜索,逐层向其祖先结点回溯。否则,进⼊该⼦树,继续按深度优先的策略进⾏搜索。回溯法在⽤来求问题的所有解时,要回溯到根,且根结点的所有⼦树都已被搜索遍才结束。⽽回溯法在⽤来求问题的任⼀解时,只要搜索到问题的⼀个解就可以结束。这种以深度优先的⽅式系统地搜索问题的解的算法称为回溯法,它适⽤于解⼀些组合数较⼤的问题。
八皇后问题的解决完整
Standardization ofsany group #QS8QHH-HHGX8Q8-GNHHJ8-HHMHGN#■ •・・WAS 1 ■ ■ ■
数据结构课程设计报告
设计题目: __________ 八皇后_______________________________________
2008 年6 月25 日
设计任务书
指导教师(签章):
2008 年6 月30 日
摘要:
八皇后问题要求在一个8 * 8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子.因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。
而本课程设计本人的目的也是通过用C++语言平台将一个8 * 8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92
种结构予以实现.使用递归方法最终将其问题变得一目了然,更加易懂。
关键词:八皇后;C++ ;递归法
1.课题综述
1.1课题的来源及意义
八皇后问题是一个古老而着名的问题,该问题是十九世纪着名的数学家高斯1850年提出的。
在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。
八皇后问题
八皇后问题
1、问题描述
八皇后问题是一个古老而著名的问题,该问题是由十九世纪著名的数学家高斯1850年提出的。在国际象棋中,皇后是最有权利的一个棋子,只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。所以高斯提出了一个问题:在8*8格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、同一条斜线上面,问共有多少种解法。
2、设计思路
1)解决行、列、斜线的冲突
行:当第i行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,还要把以i为下标的位置标记为已占领
列:规定每一列放置一个皇后,保证不会造成列上的冲突
对角线:对角线有正对角线和反对角线两个方向。当第i个皇后占领了第j列后,要同时把以(i+j)、(i-j)为下标的位置标记为已占领
2)数据结构的实现
数组a[i]:a[i]表示第i个皇后放置的列(1<=i<=8)
对角线数组:b[j](正对角线),c[j](反对角线),根据程序决定正反对角线是否放入皇后
3、数据结构设计
int Count=0;/*记录解的序号*/
int Site[QUEENS]; /*记录皇后放置在各行的位置*/
void Queen(int n);/*递归求解函数*/
{ int i;
if(n==QUEENS)
{ Output();
return;
}
}
void Output();/*输出一个解法*/
{ int i;
for(i=0;i
}
int IsValid(int n); /*判断第n个皇后放后,是否有冲突*/ { int i;
八皇后问题答案
Q * * * * * * * * * * * Q * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * 这是第2种解法如下: Q * * * * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * Q * * * 这是第3种解法如下: Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * 这是第4种解法如下: Q * * * * * * * * * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * * 这是第5种解法如下: * Q * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * 这是第6种解法如下: * Q * * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * 这是第7种解法如下: * Q * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * Q * * * * * *
leetcode 力扣 1233 八皇后 题解 算法题
题目:八皇后
设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。
注意:本题相对原题做了扩展
示例:
输入:4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
语言:Java
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> solutions = new ArrayList<List<String>>();
int[] queens = new int[n];
Arrays.fill(queens, -1);
Set<Integer> columns = new HashSet<Integer>();
Set<Integer> diagonals1 = new HashSet<Integer>();
Set<Integer> diagonals2 = new HashSet<Integer>();
八皇后问题详细的解法
如何提前发现? 在每一次扩展E结点后,都进行检查;
对检查结果如何处理? 检查合格的才继续向下扩展; 遇到不合格的“掉头就走”。
八皇后问题中的核心代码: 遍历过程函数; check函数。
解决此类问题的核心内容: 解空间树的搜索算法; 估值/判断函数:判断哪些状态适合继续扩展,或者作 为答案状态。
19
2 回溯法应用-n皇后问题
介绍过的方法: c递归回溯算法; d非递归回溯算法; 策略:能进则进,不能进则换,不能换则退。
回溯法指导思想——走不通,就掉头。
11
1 回溯法
求问题所有解:要回溯到根,且根结点的所有子树都 已被搜索遍才结束。
求任一解:只要搜索到问题的一个解就可结束。
12
1 回溯算法设计过程
step1 确定问题的解空间; step2 确定结点的扩展规则; step3 搜索解空间。
13
2 回溯法应用-加约束的枚举算法
9
双重循环,任意两个皇
queen1( )盲目的枚举算法
{ int a[9];
用a[1]~a[8]存储x1~x8
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
工学院
数据结构课程设计报告设计题目:八皇后
2008 年 6 月25 日
设计任务书
摘要:
八皇后问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子.因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。
而本课程设计本人的目的也是通过用c++语言平台将一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现.使用递归方法最终将其问题变得一目了然,更加易懂。
关键词:八皇后; c++; 递归法
目录
1. 课题综述 (1)
1.1课题的来源及意义 (1)
1.2面对的问题 (1)
2. 需求分析 (1)
2.1涉及到的知识 (2)
2.2软硬件的需求 (2)
2.3功能需求 (2)
3. 概要设计 (2)
4. 详细设计和实现 (3)
4.1算法描述及详细流程图 (3)
4.1.1算法描述 (3)
4.1.2算法流程图 (3)
5. 代码编写及详细注释 (4)
6. 程序调试 (8)
6.1调试过程、步骤及遇到的问题 (8)
7. 运行与测试 (8)
7.1运行演示 (8)
总结 (10)
致 (11)
参考文献 (12)
.
1. 课题综述
1. 1课题的来源及意义
八皇后问题是一个古老而著名的问题,该问题是十九世纪著名的数学家高斯1850年提出的。
在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。
到了现代,随着计算机技术的飞速发展,这一古老而有趣的数学游戏问题也自然而然的被搬到了计算机上。运用所学计算机知识来试着解决这个问题是个锻炼和提高我自己编程能力和独立解决问题能力的好机会,可以使我增强信心,为我以后的编程开个好头,故我选择了这个有趣的课题。
1. 2 面对的问题
1)解决冲突问题:
这个问题包括了行,列,两条对角线;
列:规定每一列放一个皇后,不会造成列上的冲突;
行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
2)使用数据结构的知识,用递归法解决问题。
2. 需求分析
2. 1 涉及到的知识
本次课程设计中,用到的主要知识有:递归法的运用,for语句的灵活运用,数据结构中树知识的灵活运用、栈及数组的掌握。
2. 2 软硬件的需求
1)系统要求:win98以上操作系统;
2) 语言平台:tc++或vc++6.0;
2. 3 功能需求
当运行程序时,在屏幕上显示每一种方法八个皇后的相对位置,要用比较直观的界面显示。
3. 概要设计
本课件学生是用循环递归循环来实现的,分别一一测试了每一种摆法,并把它拥有的92种变化表现出来。在这个程序中,我的主要思路以及思想是这样的:1)解决冲突问题:
这个问题包括了行,列,两条对角线;
列:规定每一列放一个皇后,不会造成列上的冲突;
行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
对角线:对角线有两个方向。在这我把这两条对角线称为:主对角线和从对角线。在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。
因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占
领状态。
2)数据结构的实现
而对于数据结构的实现,学生则是着重于:
数组a[I]:a [I]表示第I个皇后放置的列;I的围:1..8;
对角线数组:b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后;
4. 详细设计和实现
4. 1 算法描述及详细流程图
4.1.1 算法描述
A、数据初始化。
B、从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要
求),先测试当前位置(n,m)是否等于0(未被占领)。如果是,摆放第n个皇后,并宣布占领(记得横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。
C、使用数组实现回溯法的思想。
D、当n>8时,便打印出结果。
E、输出函数我使用printf输出,运行形式为:第m种方法为:* * * * * * * *
4.1.2 算法流程图
5. 代码编写及详细注释
#include
#include
#include
#include
#include
#define QUEENS 8
int iCount = 0; //!记录解的序号的全局变量。
int Site[QUEENS]; //!记录皇后在各行上的放置位置的全局数组。
void Queen(int n); //!递归求解的函数。
void Output();//!输出一个解。
int IsValid(int n);
//!判断第n个皇后放上去之后,是否有〉冲突。
void main() /*----------------------------Main:主函数。----------------------------*/
{ system("title 叶青--递归算法八皇后问题");
cout<<" "<<"八皇后的解法:"<