#八皇后问题
###问题描述:
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
###简化问题:
由于八皇后问题的正确答案为92种排列方案,由于正确的棋子放置方式实在太多,难以一一列举,所以先简化问题,解决四皇后的排列,即将8×8棋局改为4×4棋局,规则不变
###建立模型:
要使用C++解决这个问题,首先要建立模型,让问题能够使用数学和C++的控制语句来解决。
将棋盘模拟为一个坐标轴,使用一个数组index将每个棋子定位到坐标轴中,index数组的下标为横坐标值,index[i]的值为纵坐标值,如下图所示,index[0] = 1 ; index[1] = 4 ; index[2] = 2 ; index[3] = 3


#方案1----枚举法:
将所有可能的棋子放置情况全部列举出来,一一判断是否合乎条件
###C++程序:

#include<iostream>
using namespace std;//判断棋子放置方式是否正确
bool Judge(int *index) {for (int i = 0; i < 4; i++){for (int j = i + 1 ; j < 4; j++) {//判断棋子是否在同一行,或某一对角线上//1,横坐标不同      i与j不相等//2,纵坐标不同      index[i]与index[j]不相等//3,不在同一对角线  index[i]- index[j]的绝对值和j-i的绝对值不相等if (index[i] == index[j] || abs(index[i]- index[j])==j-i){return false;}}}return true;
}//打印正确的棋子放置方式
void Sloution(int *index) {cout << "四皇后问题的一种正确解法,横坐标从0到4的4列上,纵坐标的值依次是:";for (int i = 0; i < 4; i++){cout << index[i];}cout << endl;
}int main() {int index[8];//多层循环,穷举每一种放置方式for (index[0] = 1; index[0] <= 4 ; index[0]++){for (index[1] = 1; index[1] <= 4; index[1]++) {for (index[2] = 1; index[2] <= 4; index[2]++) {for (index[3] = 1; index[3] <= 4; index[3]++) {//判断棋子放置是否合乎规则,正确则打印,不正确则继续if (Judge(index)){Sloution(index);}else {continue;}}}}}cin.get();return 0;}

上述程序使用了4个for循环来模拟所有可能出现的棋子放置情况,Judge()方法用来判断是否合乎条件

###运行结果:

###正确结果的演示:
纵坐标:2413

纵坐标:3142

##枚举法的优化:
枚举法解决此四皇后问题需要的循环次数太多,四皇后需要4X4X4X4次遍历,才能将所有可能的情况列举出来,八皇后更是要8X8X8X8X8X8X8X8次遍历
枚举法可以进行优化,即若在放置第2,或3个棋子,即没有将棋子全部放入棋盘中时,进行判断,将不符合要求的情况直接排除,不再继续循环,这样能够大大减少循环次数,不必模拟所有棋子放置方式
优化方式:在main方法中做优化,增加判断语句

int main() {int index[8];//多层循环,穷举每一种放置方式for (index[0] = 1; index[0] <= 4; index[0]++) {for (index[1] = 1; index[1] <= 4; index[1]++) {//增加判断if(Judge(index, 2))for (index[2] = 1; index[2] <= 4; index[2]++) {//增加判断if (Judge(index, 3))for (index[3] = 1; index[3] <= 4; index[3]++) {//判断棋子放置是否合乎规则,正确则打印,不正确则继续if (Judge(index, 4)) {Sloution(index);}else {continue;}}}}}cin.get();return 0;
}

#方案2----回溯法:
main函数:


int main() {int index[4] = { 0 };int i = 0;while (i > -1) {index[i]++;while (index[i] < 6 && _judge(index, i)) {index[i]++;}if (index[i] <= 4) {if (i == 3) {//是四皇后的正确结果,调用函数打印正确答案result(index);}else {i++;index[i] = 0;}}else {i--;}}cin.get();return 0;
}

_judge函数:

inline bool _judge(int *index, int num) {for (int i = 0; i < num; i++) {if (index[i] == index[num] || abs(index[i] - index[num]) == num - i) {return true;}}return false;}

result函数:

inline void result(int *index) {cout << "四皇后问题的一种正确解法,横坐标从0到4的4列上,纵坐标的值依次是:";for (int i = 0; i < 4; i++) {cout << index[i];}cout << endl;
}


##使用递归优化程序:
上述程序太难懂,可以使用递归优化上述程序,如下:
result函数和_judge函数不变
回调函数:

void callback(int *index,int i) {if (i > 3){result(index);}else{int j = 0;while (++j <= 4) {index[i] = j;if (_judge(index, i) == 0) {callback(index,i+1);}}}
}

main函数:

int main() {int index[4] = { 0,0,0,0 };int i = 0;callback(index,i);cin.get();return 0;
}

#方案3----回溯法结合递归和栈数据结构
在严蔚敏编著的C语言数据结构栈数据结构部分,书中提及使用栈解决四皇后问题

栈数据结构解决和回溯相关的问题时非常的方便易懂,下面介绍一下使用栈解决四皇后问题,这是本文最简单易懂的方法,但是需要实现编写栈数据结构,当然也可以使用STL中的栈

#include "assist.h"
#include"Stack.h"
#include<iostream>
//创建一个全局栈
Stack<int> stack(11);
//回调函数
void callback() {if (stack.getSize() == 3) {cout << "正确答案" << endl;stack.Print();}else {int j = 0;while (++j <= 4){//进栈stack.Push(j);if (_judge( stack.getElements(), stack.getSize()) == 0) {//打印整个栈中的数据stack.Print();cout << stack.getSize() << endl;callback();}//弹栈stack.Pop();}}
}int main() {callback();cin.get();return 0;
}

经典算法问题-01-八皇后相关推荐

  1. 一本通DFS经典:1214:八皇后

    1214:八皇后 一.数学模型 八皇后问题描述的是八个国际象棋中皇后棋子如何摆放的问题,而实际上可以抽象成8*8二维空间中的一种特殊选点问题:任意选择8个点,其中任意两个点:不同行不同列不同对角线: ...

  2. 算法:递归-八皇后问题(回溯算法)

    1.问题介绍 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯・贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不 ...

  3. 【经典算法】第八回:桶排序

    1.概述 桶排序 (Bucket sort)或所谓的箱排序,工作的原理是将阵列分到有限数量的桶子里.每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序).桶排序是鸽巢排序 ...

  4. 数据结构与算法-- 八皇后问题(多种实现方案)

    八皇后问题解法一(排列筛选法) 本篇我们承接上一篇中的思想,想到了一个经典的算法题,八皇后问题: 题目:在8*8的国际象棋上摆放8个皇后,使得其互相不能攻击,即任意两个换后不能在同一行,同一列,或者同 ...

  5. python深度优先算法 八皇后_八皇后问题——DFS(深度优先搜索)

    八皇后问题,是在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法? 算法思路: 八皇后问题实质为一种深度优先(DFS)搜索问题. ...

  6. Prolog学习:数独和八皇后问题

    上一篇简单介绍了下Prolog的一些基本概念,今天我们来利用这些基本概念解决两个问题:数独和八皇后问题. 数独 数独是一个很经典的游戏: 玩家需要根据n×n盘面上的已知数字,推理出所有剩余空格的数字, ...

  7. 递归回溯解决八皇后问题

    文章目录 前言 八皇后问题 问题解析 代码实现 完整代码 前言 八皇后问题是一个古老而著名的问题,是回溯算法的典型例题.该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇 ...

  8. 数据结构之栈与递归的应用(八皇后递归解法)

    前面几节讲述了递归的一般应用,本节讲一下递归的另一个重要的应用场合回溯算法,利用函数调用的活动对象可以保存回溯算法中重要的变量信息 . 递归与回溯 递归在程序设计中也常用于需要回溯算法的场合. 回溯算 ...

  9. 八皇后问题遗传算法c语言,遗传算法解决八皇后问题

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 八皇后问题描述 19 世纪著名的数学家 Gauss 在 1850 年提出八皇后问题后, 该问题成为各类语言程序设计的经典 ...

  10. 数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题

    文章目录 前言 一.数据结构 1.1 线性结构 1.2 非线性结构 二.数据结构与算法 2.1 两者之间的关系 2.2 两者重要性 三.实际编程中遇到的问题 3.1 单链表问题 3.2 五子棋问题 3 ...

最新文章

  1. 认识下PHP如何使用 phpmailer 发送电子邮件
  2. Python selenium根据class定位页面元素,xpath定位
  3. ACdream OJ 1140 Counting Triangles
  4. (46)分析 INT 0x2E 和 sysenter
  5. 中国陶瓷辊棒市场全景调查及供需格局预测报告2022-2028年版
  6. NSCTF-部分题目wp
  7. python scrapy request_Scrapy中的Request和日志分析|python基础教程|python入门|python教程...
  8. java字节码_掌握Java字节码
  9. 使用VLC转码,在HTML5页面播放实时监控
  10. SHA256 的C语言实现
  11. 中国能源变革令西方相形见绌
  12. python装饰器与闭包_Python:函数装饰器和闭包
  13. windows编译python扩展Unable to find vcvarsall
  14. win10计算机如何切换用户名,win10怎么改用户名_win10怎么更改用户名
  15. 环境微生物学练习题及答案
  16. 仙人掌之歌——大规模高速扩张(1)
  17. SuperMemo导出html,使用思维导图和SuperMemo一起来快速复习(1)
  18. Selenium中的鼠标单击事件
  19. 三大运营商的云计算之殇
  20. Java 调用Google Map Api解析地址,解析经纬度实例

热门文章

  1. 什么是云服务举例说明_什么叫云服务举例说明(云服务器实例是什么)
  2. 克莱斯勒等公司宣布召回缺陷汽车
  3. Android SDCard中写入文件
  4. 双光耦开关电源电路图_开关电源中的光耦典型电路设计分析
  5. Mysql中的straight_join
  6. canvas制作圆角矩形(包括填充矩形的功能)
  7. MATLAB中求某个函数的积分并绘图
  8. 基努·里维斯继续出演《黑客帝国4》|| 程序员吐槽大会精选片段
  9. Android Camera2 Opengles2.0 实时滤镜(冷暖色/放大镜/模糊/美颜)
  10. C语言用数组模拟实现栈(LIFO)