【算法训练】八皇后问题回溯算法求解
2016-04-27 22:09
330 查看
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如今有一个8*8的棋盘,如何将 8 个皇后放在棋盘上,使它们谁也不能被吃掉!这就是著名的八皇后问题。
分析:这个问题在求解时可以使用回溯算法去分析问题——在第一行放上棋子以后,递归到第二行,找到一个能放置棋子的位置,将棋子放上后,递归到第三行。。 。。。 依次类推,但是会找到一行,没有办法放置棋子,也就是说,放置位置上,行、列、斜线都已经有棋子了,那么这时就要返回到上一步,重新放置上一步的棋子,再走下一步,直到下一步能放置棋子便好。整个棋盘放好的标志是第八行已经放置了棋子。
使用回溯算法思考后,思路就很清晰了,虽然这个算法时间复杂度不低,但是它属于那种很好理解的思路,代码如下:
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如今有一个8*8的棋盘,如何将 8 个皇后放在棋盘上,使它们谁也不能被吃掉!这就是著名的八皇后问题。
分析:这个问题在求解时可以使用回溯算法去分析问题——在第一行放上棋子以后,递归到第二行,找到一个能放置棋子的位置,将棋子放上后,递归到第三行。。 。。。 依次类推,但是会找到一行,没有办法放置棋子,也就是说,放置位置上,行、列、斜线都已经有棋子了,那么这时就要返回到上一步,重新放置上一步的棋子,再走下一步,直到下一步能放置棋子便好。整个棋盘放好的标志是第八行已经放置了棋子。
使用回溯算法思考后,思路就很清晰了,虽然这个算法时间复杂度不低,但是它属于那种很好理解的思路,代码如下:
#include<stdio.h> #include<stdlib.h> //首先定义几个全局的数组来当作存放皇后的标志位 int cnt=0; //cnt 用来计算解的个数 int col[8]={0}; //数组col 用来标志本行的某列是否存放了皇后 int left[15]={0}; //数组left用来标志该位置的左对角线是否放置皇后 int right[15]={0}; //数组right 作用同上 int Q[8]={-1}; //数组Q用来存放最后的结果 //当第八个皇后放置完成后,输出这个解 void PrintQueen() { printf("\n第%d个解:\n",++cnt); for(int i=0;i<8;++i){ for(int j=0;j<8;++j){ if(Q[i]==j) printf("Q "); else printf("x "); } printf("\n"); } } //放置皇后(回朔+贪心) void Queen(int i){ for(int j=0;j<8;++j){ if(col[j]==0&&left[i+j]==0&&right[7+i-j]==0){ //判断每一列 每条斜线(左右斜线)是否都无棋子是则放置皇后 Q[i]=j; //Q[]数组存放这一行的有皇后列数 col[j]=left[i+j]=right[7+i-j]=1; //放好以后全部置1,表示这一列,这一左右对角线都不能再放置皇后 if(i<7) Queen(i+1); //如果皇后还没有放置在最后一行,那么递归调用放置皇后 else{ PrintQueen();//否则,说明皇后放置完成,就输出它 } //抹掉这个位置的皇后,后重新摆放 Q[i]=-1; col[j]=left[i+j]=right[7+i-j]=0; } } } int main(void){ Queen(0); return 0; }
相关文章推荐
- (多核DSP快速入门)4.编译测试多核DSP实例Vlfft
- js map
- AngularJS 深入理解 $scope
- 自动化脚本多线程运行
- TP_框架下的GD图片处理类(含基本php图片处理思路)
- leetcode-8. String to Integer (atoi)
- CSockets类重写CSocket
- CreateWindows
- IOS开发-UIView之动画效果的实现方法(
- Service基础使用
- 构建乘积数组
- 判断摩天是该年第几天【数组】;
- 异常处理
- php 正则表达式 数组
- odoo 8.0 多核启用,python多核心利用测试
- android 中layer-list的用法
- 归纳决策树ID3(Java实现)
- c++字符小写转大写
- 冲刺第五天
- 定位DSP 非法中断