8皇后及其普及(N)——小试牛刀(1)

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻

击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。——————————摘自《度娘百科》
       八皇后问题是回溯与搜索的一个很典型的例子。算法关键就是矩阵上。如果在同一行,则行号相同(列同上)。如果都在“/”对角线上,则行列和相同;如果都在“\"对角线上,则行列差相同。
我们可以以行为条件搜索,放置一个以后定下对角线和列号,就像下面的程序:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<iomanip>
 5 using namespace std;
 6 bool d[100]={0},b[100]={0},c[100]={0};         //定义行列数组,对角线数组。
 7 int sum=0,a[100];
 8 int search(int);
 9 int print();
10 int main()
11  {
12  search(1);                                                   //用 search(int)函数计算。
13  }
14 int search(int i)
15 {
16  int j;
17  for(j=1;j<=8;j++)
18     if((!b[j])&&(!c[i+j])&&(!d[i-j+7]))
19     {
20      a[i]=j;                                                             //放置皇后。声明占用的行、列、对角线。
21      b[j]=i;
22      c[i+j]=1;
23      d[i-j+7]=1;
24      if(i==n)print();                                                //若8个皇后都放好,输出。
25        else search(i+1);                                         //继续递归放置皇后,回溯。
26      b[j]=0;
27      c[i+j]=0;
28      d[i-j+7]=0;
29     }
30 }
31 int print()
32 {
33  int i;
34  sum++;                                                       //方案数累加
35  cout<<sum<<endl;
36  for(i=1;i<=n;i++)                                         //输出方案
37    cout<<setw(4)<<a[i];
38  cout<<endl;
39 }

程序是这样的:

其中”92“代表方案,后面的数是第几列(行是从一到八)
解释一下就是(1,8)(2,4)(3,1)(4,3)(5,6)(6,2)(7,7)(8,5)

拓展一下就是变成N皇后问题:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
using namespace std;
bool d[100]={0},b[100]={0},c[100]={0};
int sum=0,a[100],n;                                           //注意里面多了个N。
int search(int);
int print();
int main()
 {
  cin>>n;                                                         //输入N。
 search(1);
 }
int search(int i)
{
 int j;
 for(j=1;j<=n;j++)
    if((!b[j])&&(!c[i+j])&&(!d[i-j+n-1]))
    {
     a[i]=j;
     b[j]=i;
     c[i+j]=1;
     d[i-j+n-1]=1;
     if(i==n)print();
       else search(i+1);
     b[j]=0;
     c[i+j]=0;
     d[i-j+n-1]=0;
    }
}
int print()
{
 int i;
 sum++;
 cout<<sum<<endl;
 for(i=1;i<=n;i++)
   cout<<setw(4)<<a[i];
 cout<<endl;
}
时间: 2024-11-03 22:43:09

8皇后及其普及(N)——小试牛刀(1)的相关文章

Shell 脚本小试牛刀(4) -- 创建 git 仓库

之前写过一个<Git 使用及进阶实战>,其中讲解了很多Git 的基本用法,包括创建仓库等使用以及一些错误排除,还是挺好的 GIT 普及博文. 我经常会在本地家用主机 /服务器上创建 git 仓库,可能一个语言的学习或者一个项目都需要一个git 仓库.不得不说创建仓库还是挺烦人的,有的时候会遗漏或者忘记命令,于是我写了一个简单的脚本来简化创建GIT 仓库的繁杂无趣的过程: #!/bin/bash # (C) 2014 Yunlong Zhou <[email protected]>

关于8皇后问题的一些旧事

最早看到8皇后应该是上计算机系的什么课?应该是<算法>?好像没有这门课,那最有可能的就是<数据结构>了,我们数学系也有<数据结构>,不过是普及版,要求没有计算机系高,毕竟我们系应用方面的只是一小部分.当时我应该是懂了的吧,不过我不记得我完整的写下来过这个算法,完全没有印象了. 不过类似的算法,我应该是遇到过的,在<数学模型>那门课里面,当时要针对一个问题建模,和8皇后问题应该是一样的算法,就是遍历,剪枝?回溯一类的吧.大致是有一堆不规则的数,要尽量接近的凑出

八皇后问题

#include <stdio.h> #include <stdlib.h> #define Maxsize 100 typedef struct node{ int _x; int _y; }chessman,*chess; static int cnt=0; static chessman c[Maxsize]; bool isOK(chess c,chessman cm,int c_len){ //判断是否能将当前皇后加入棋盘中 for(int i=0;i<c_len;

8皇后

#include <stdio.h>#include <math.h>#include <time.h>#define max 1000int sum=0;bool place (int k,int x[]){ for (int j=1;j<k;j++)if ((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) return false;return true;} void backtrack (int t,int x[],int

2n皇后问题

在蓝桥杯基础训练题中,出现这样一道题目: 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行.同一列或同一条对角线上.问总共有多少种放法?n小于等于8. 输入格式 输入的第一行为一个整数n,表示棋盘的大小. 接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后. 输出格式 输出一个整数,表示总

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr

回溯法——求解N皇后问题

问题描述 八皇后问题是十九世纪著名数学家高斯于1850年提出的.问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上.可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行.同一列或同一斜线上. 问题分析 我们以最简单的4皇后问题分析,显然,为了使皇后不相互攻击,首先考虑每一行只能放一个皇后,我们以X[1,2,3-.N]代表此问题的解数组,X[N]代表在第N行第X[N]列放了一个皇后,例如,X[2

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

2017年8月14日套题记录 | 普及组

写在前面 今天登洛谷发现离Noip剩下88天了??(虽然看起有点久),然后觉得似乎水了一个暑假什么也没做(虽然学了点数据结构和一些奇奇Gaygay的东西),于是打开题库发现去年Long Happy的集训套题我似乎没有提交过,那就一天一套题,顺便码个题解+心得(雾? T2.传作业 题目描述 某十三同学一日上学迟到,此时已经开始上早自习了,所以他只好请同学帮忙把作业传到组长那里.由于刚开学不久,某十三同学还没来得及认识所有同学,所以传作业时只好找熟悉的同学.已知某十三与组长之间有N个他熟悉的同学,并