八皇后问题
来源:互联网 发布:流行网络用语 编辑:程序博客网 时间:2024/05/09 15:29
1、介绍
先上张图来说明用回溯法解八皇后问题的每一步:
2、程序
对着严蔚敏的书写的,写好后运行竟然一次性成功了,没有任何bug,我鸡冻了。
上代码:
//N皇后问题#include <iostream>using namespace std;#define N 8bool matrix[N + 1][N + 1] = {0};bool IsLegal(bool matrix[N + 1][N + 1], const int &i, const int &j){//判断前面的i-1个棋子与matrix[i][j]是否冲突,i为1时合法for (int m = 1; m <= i - 1; ++m) {for (int n = 1; n <= N; ++n) {//实际每一行只有一个棋子if (matrix[m][n] == 1) {if ( n == j || abs(i - m) == abs(j - n) )//key, not badreturn false;}}}return true;}void Print(bool matrix[N + 1][N + 1]){static int count = 1;printf("Case %d:\n", count++);for (int i = 1; i <= N; i++) {for (int j = 1; j <= N; j++) {matrix[i][j] == 1 ? printf("%c ", 2) : printf(". ");}cout << endl;}cout << endl;}void Trial(const int i){//进入本函数时,在N*N的棋盘前i-1行已放置了互不攻击的i-1个棋子//现从第i行起继续为后续棋子选择合适位置if (i > N)//输出当前的合法布局Print(matrix);elsefor (int j = 1; j <= N; ++j) {matrix[i][j] = 1;if ( IsLegal(matrix, i, j) )Trial(i + 1);matrix[i][j] = 0;}}int main(void){Trial(1);return 0;}
运行结果:
3、数学问题
关于n皇后的解的个数(8皇后是92个解):
na(n)1120304251064740892935210724112680121420013737121436559615227918416147725121795815104186660906241949680578482039029188884213146662227122226910087016442324233937684440242275141719737362522078934358083522622317699616364044
独立解的问题我就不多提了。目前这个数列还没找到通项公式。有意思的是,高斯算八皇后的解的个数时,他算错了,他的答案是76种,不知道他漏了哪种,呵呵。(不过也是4的倍数)
//N皇后问题#include <iostream>using namespace std;#define N 8int matrix[N + 1][N + 1] = {0};//matrix[0][j]为空,matrix[i][0]中放第i行的皇后的列坐标(从1开始记)bool IsLegal(const int &i, const int &j){//判断前面的i-1个棋子(坐标是matrix[m][n])与matrix[i][j]是否冲突,i为1时合法for (int m = 1; m <= i - 1; ++m) {int n = matrix[m][0];if ( n == j || abs(i - m) == abs(j - n) )return false;}return true;}void Print(void){static int count = 1;printf("Case %d:\n", count++);for (int i = 1; i <= N; i++) {for (int j = 1; j <= N; j++) {matrix[i][j] == 1 ? printf("%c ", 2) : printf(". ");}cout << endl;}cout << endl;}void Trial(const int &i){//进入本函数时,在N*N的棋盘前i-1行已放置了互不攻击的i-1个棋子//现从第i行起继续为后续棋子选择合适位置if (i > N)//输出当前的合法布局Print();elsefor (int j = 1; j <= N; ++j) {matrix[i][j] = 1;if ( IsLegal(i, j) ) {matrix[i][0] = j;Trial(i + 1);}matrix[i][j] = 0;}}int main(void){Trial(1);return 0;}
4、想法
那个Trial递归函数我还没弄明白,对着书抄的,要是自己想,难。还有待研究推广。
2012/5/8 更新
把判断是否合法的IsLegal函数优化了,原来的程序是O(N^3),现在是 O(N^2):
//N皇后问题#include <iostream>using namespace std;#define N 8int matrix[N + 1][N + 1] = {0};//matrix[0][j]为空,matrix[i][0]中放第i行的皇后的列坐标(从1开始记)bool IsLegal(const int &i, const int &j){//判断前面的i-1个棋子(坐标是matrix[m][n])与matrix[i][j]是否冲突,i为1时合法for (int m = 1; m <= i - 1; ++m) {int n = matrix[m][0];if ( n == j || abs(i - m) == abs(j - n) )return false;}return true;}void Print(void){static int count = 1;printf("Case %d:\n", count++);for (int i = 1; i <= N; i++) {for (int j = 1; j <= N; j++) {matrix[i][j] == 1 ? printf("%c ", 2) : printf(". ");}cout << endl;}cout << endl;}void Trial(const int &i){//进入本函数时,在N*N的棋盘前i-1行已放置了互不攻击的i-1个棋子//现从第i行起继续为后续棋子选择合适位置if (i > N)//输出当前的合法布局Print();elsefor (int j = 1; j <= N; ++j) {matrix[i][j] = 1;if ( IsLegal(i, j) ) {matrix[i][0] = j;Trial(i + 1);}matrix[i][j] = 0;}}int main(void){Trial(1);return 0;}
- 八皇后 n皇后 问题
- 八皇后N皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题(2)
- 八皇后问题(3)
- 八皇后问题
- 八皇后问题程序
- 浅谈八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题求解
- 八皇后问题
- 八皇后问题
- 八皇后问题
- Quartz 2D 学习总结
- loner_li 机试题 编程实现 冒泡排序
- mac pro开机密码忘记了
- Dijkstra算法
- rman之控制文件的自动备份和还原
- 八皇后问题
- js 防止表单被重复提交
- 解决oracle11g 空表不能exp导出的问题
- Oracle RAC 环境下的 v$log v$logfile
- loner_li 机试题 编程遍历所有的Textbox控件 ,设置其值为空
- 如何从Eclipse导入github上的项目源码
- java服务器端开发相关
- 数据结构学习之栈和栈的操作源码
- 看《Java 程序员在写 SQL 程序时候常犯的 10 个错误》之后