八皇后问题
来源:互联网 发布:往届生银行知乎 编辑:程序博客网 时间:2024/06/10 22:21
方案一
说的有点夸装,实际上并不只是八行代码,加上前面的变量声明之类的一共有40多行的样子吧,好像是
在知乎上看到的,现在有时间再把它写下来:
其中用到了一些c++11特性,例如lambda 以及给予范围的 for循环。
其他的没什么好说的,看代码,上面也有注释的。
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 #include <set> 5 using namespace std; 6 void eightQueen(int n); 7 int main() 8 { 9 eightQueen(8);10 system("pause");11 return 0;12 }13 14 void eightQueen(int n)15 {16 int count = 0;17 vector<int> border(n);18 for (int i = 0; i < n; ++i)19 border[i] = i + 1; //这一步就决定了每一行的上下左右都不会有其他的皇后20 vector<int> afterAdd(8);21 vector<int> afterSub(8);22 for(;;){23 transform(border.begin(), border.end(), afterAdd.begin(), 24 [](int i)->int{static int index = 1; i += index; index++; return i; });25 transform(border.begin(), border.end(), afterSub.begin(), 26 [](int i)->int{static int index = 1; i -= index; index++; return i; });27 set<int> afterAddSet(afterAdd.begin(), afterAdd.end());28 set<int> afterSubSet(afterSub.begin(), afterSub.end());29 if (afterAddSet.size() == 8 && afterSubSet.size() == 8){ //如果斜对角线上都没有元素话30 ++count;31 for (auto c : border)32 cout << c << ' ';33 cout << endl;34 }35 if (!next_permutation(border.begin(), border.end())){36 cout << "Total : " << count << endl;37 break;38 }39 }40 }
嗯大概就是这样,下面是结果:
1 5 8 6 3 7 2 4 1 6 8 3 7 4 2 5 1 7 4 6 8 2 5 3 1 7 5 8 2 4 6 3 2 4 6 8 3 1 7 5 2 5 7 1 3 8 6 4 2 5 7 4 1 8 6 3 2 6 1 7 4 8 3 5 2 6 8 3 1 4 7 5 2 7 3 6 8 5 1 4 2 7 5 8 1 4 6 3 2 8 6 1 3 5 7 4 3 1 7 5 8 2 4 6 3 5 2 8 1 7 4 6 3 5 2 8 6 4 7 1 3 5 7 1 4 2 8 6 3 5 8 4 1 7 2 6 3 6 2 5 8 1 7 4 3 6 2 7 1 4 8 5 3 6 2 7 5 1 8 4 3 6 4 1 8 5 7 2 3 6 4 2 8 5 7 1 3 6 8 1 4 7 5 2 3 6 8 1 5 7 2 4 3 6 8 2 4 1 7 5 3 7 2 8 5 1 4 6 3 7 2 8 6 4 1 5 3 8 4 7 1 6 2 5 4 1 5 8 2 7 3 6 4 1 5 8 6 3 7 2 4 2 5 8 6 1 3 7 4 2 7 3 6 8 1 5 4 2 7 3 6 8 5 1 4 2 7 5 1 8 6 3 4 2 8 5 7 1 3 6 4 2 8 6 1 3 5 7 4 6 1 5 2 8 3 7 4 6 8 2 7 1 3 5 4 6 8 3 1 7 5 2 4 7 1 8 5 2 6 3 4 7 3 8 2 5 1 6 4 7 5 2 6 1 3 8 4 7 5 3 1 6 8 2 4 8 1 3 6 2 7 5 4 8 1 5 7 2 6 3 4 8 5 3 1 7 2 6 5 1 4 6 8 2 7 3 5 1 8 4 2 7 3 6 5 1 8 6 3 7 2 4 5 2 4 6 8 3 1 7 5 2 4 7 3 8 6 1 5 2 6 1 7 4 8 3 5 2 8 1 4 7 3 6 5 3 1 6 8 2 4 7 5 3 1 7 2 8 6 4 5 3 8 4 7 1 6 2 5 7 1 3 8 6 4 2 5 7 1 4 2 8 6 3 5 7 2 4 8 1 3 6 5 7 2 6 3 1 4 8 5 7 2 6 3 1 8 4 5 7 4 1 3 8 6 2 5 8 4 1 3 6 2 7 5 8 4 1 7 2 6 3 6 1 5 2 8 3 7 4 6 2 7 1 3 5 8 4 6 2 7 1 4 8 5 3 6 3 1 7 5 8 2 4 6 3 1 8 4 2 7 5 6 3 1 8 5 2 4 7 6 3 5 7 1 4 2 8 6 3 5 8 1 4 2 7 6 3 7 2 4 8 1 5 6 3 7 2 8 5 1 4 6 3 7 4 1 8 2 5 6 4 1 5 8 2 7 3 6 4 2 8 5 7 1 3 6 4 7 1 3 5 2 8 6 4 7 1 8 2 5 3 6 8 2 4 1 7 5 3 7 1 3 8 6 4 2 5 7 2 4 1 8 5 3 6 7 2 6 3 1 4 8 5 7 3 1 6 8 5 2 4 7 3 8 2 5 1 6 4 7 4 2 5 8 1 3 6 7 4 2 8 6 1 3 5 7 5 3 1 6 8 2 4 8 2 4 1 7 5 3 6 8 2 5 3 1 7 4 6 8 3 1 6 2 5 7 4 8 4 1 3 6 2 7 5 Total : 92
一共有92种方式,由于是枚举了所有的可能情况,所以用时稍微有一点长。
http://www.cnblogs.com/-wang-cheng/p/4854484.html
###方案二1问题描述
N皇后问题,就是如何将国际象棋中的N个皇后放在N*N的棋盘上而不会互相攻击,是一种通过枚举,再递归、回溯的思想。
2思路
以8皇后问题为例,可知在8*8二维数组中,每个点用data[i][j]表示(0 <= i,j <= 7)。
其中其主对角线上(左上到右下)的每个点的i-j+7的值都相同(范围0-14)。
其从对角线上(右上到左下)的每个点i+j的值都相同(返回0-14)。
且其中每个子方阵的主对角线之间的i-j+7的值都不同,从对角线之间的i+j的值也不同。
如在4*4的子方阵中的data[3][4]:
穿过data[3][4]的主对角线:3-4+7=6
穿过data[3][4]的从对角线:3+4=7
若是穿过data[4][4],其主对角线:4-4+7=7;从对角线:4+4=8
为何要研究这种规律呢?
因为摆放皇后时,可知N个皇后肯定在不同行,不同列,以及不同对角线上。因此每在一个不同行摆放一个皇后时,首先要检查该列是不是被占用,以及穿过该点的主、从对角线是否被占用,若是则要换列。
3具体代码
bool checkCol[]:表示每一列的占用情况,大小1*N
bool leftCross[]:表示穿过该放置点(i,j)的主对角线的占用情况,其下标为i-j+7。
bool rightCross[]:表示穿过该放置点(i,j)的从对角线的占用情况,下标为i+j。
int * *data:N*N棋盘。
#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;int count_Method = 0;int queenNum = 0;bool *checkCol;bool *leftCross;bool *rightCross;int **data;void getNQueens( int );/*功能: 求解放置8皇后方案的个数。输入:N个皇后个数无返回:int:放置8皇后方案的个数*/int PlaceQueenMethodNum(int N){ /*在这里实现功能*/ queenNum = N; data = (int **)malloc(N*sizeof(int*)); for(int i = 0; i < N; i++){ data[i] = (int *)malloc(N*sizeof(int)); } checkCol = (bool *)malloc(N*sizeof(bool)); //column(列)占用情况,占用为true,反之false leftCross = (bool *)malloc((2*N-1)*sizeof(bool));//左对角线 rightCross = (bool *)malloc((2*N-1)*sizeof(bool));//右对角线情况 for(int i = 0; i < 2*N-1; i++ ) //主、从对角线 leftCross[i] = rightCross[i] = false; //表示安全 for(int i = 0; i < N; i++ )//chess { checkCol[i] = false; for(int j = 0; j < N; j++ ){ data[i][j] = 0; } } getNQueens( 0 ); return count_Method;}void getNQueens( int row ){ if( row == queenNum )//N个皇后安置就位,解决方案+1 { count_Method++; return; } for( int column = 0; column < queenNum; column++ ) { if( !checkCol[column] && leftCross[row-column+7] == false && rightCross[row+column] == false ) { data[row][column] = 1; //安置皇后 checkCol[column] = true; //此列被占 leftCross[row-column+7] = true; //主对角线被占 rightCross[row+column] = true; //从对角线被占 getNQueens(row+1); //下一个皇后 //此步重置,列右移继续找 data[row][column] = 0; checkCol[column] = false; leftCross[row-column+7] = false; rightCross[row+column] = false; } }}int main(){ int n; cin>>n; cout<<PlaceQueenMethodNum(n); system("pause");}
http://blog.csdn.net/chenloxiaoea/article/details/50246523
- 八皇后 n皇后 问题
- 八皇后N皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题(2)
- 八皇后问题(3)
- 八皇后问题
- 八皇后问题程序
- 浅谈八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题求解
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 整数奇偶排序
- 网络编程服务器与客户端实现代码详解
- framework watchdog源码分析
- 一文读懂Shell脚本中循环语句for,while,until用法
- python入门(十):文件的操作详解
- 八皇后问题
- 合影效果
- C语言数据结构2——双向链表的实现
- 汇编中loop格式用法分析
- 146_IO_原理_分类_标准步骤
- Opencv并行访问图像像素
- 分数线划定
- 【暑期多校联萌
- 编译Android2.3出现的问题