八皇后问题

来源:互联网 发布:淘宝买高达模型 编辑:程序博客网 时间:2024/06/15 10:57

八皇后问题,回溯剪枝。

代码如下,仅供参考。

/******************************************************************** 程序说明:八皇后问题*在一个8*8的棋盘上放置8个皇后,不允许出现两个皇后在同一行、*同一列、主对角线和从对角线上。* 分析:(1)不在同一行和同一列上,这个比较好判断;*(2)不在同一条主对角线(或从对角线上)这个可分析如下:*对于任意一个点 dot[i][j](0<=i,j<=7),与该点在同一主*对角线上的点,其 i-j+7 的值相等,并且范围在[0,14];*与该点在同一从对角线上的点,其 i+j 的值相等,范围在*[0,14]。即是说:若两个点a[ik][jk]和b[if][jf]在同一*主对角线上,则 ik-jk+7 == if-jf+7 (之所以要 + 7,是*因为 i-j 可能 < 0,这是为了后续在代码中用数组作记录*方便);若两个点a[ik][jk]和b[if][jf]在同一从对角线上,*则 ik+jk == if+jf。故判断在坐标 (i,j) 的位置放上皇后*后,是否存在主对角线和从对角线上有其它的皇后,只需要*查询对应的记录数组就可以。*(3)在8*8的矩阵中,主对角线共有2*8-1=15条,反对角线(从对角线)*共有2*8-1=15条;*(4)时间复杂度为:O(n^2)* 其它:该8皇后问题也可以改为4皇后问题,只需要把对应的条件修改即*可。*******************************************************************/#define LOCAL#include<iostream>#include<cstdio>using namespace std;int chessBoard[8][8];//棋盘,0代表此位置无皇后,1代表此位置有皇后int columnStates[8];//列状态,0代表此列没有皇后,1代表此列有皇后int mainDiagStates[15];//主对角线状态,0代表该条主对角线上无皇后,1代表该条主对角线上有皇后int countDiagStates[15];//从对角线(反对角线)状态,0,1代表的意义,同上。int planCount;//共有多少种放置方案void eightQueens(int i) {//尝试在第i行上放上一个皇后if (8 == i) {//由于行号的范围为:[0,7],所以当得到行参数坐标i==8时,++planCount;cout << "第 " << planCount << " 种放置方案:" << endl;for (int k = 0; k < 8; k++) {//表明前[0,7]行上已经成功放上皇后了,for (int w = 0; w < 8; w++) //故直接输出结果。cout << chessBoard[k][w] << " ";cout << endl;}cout << "------------------------" << endl;return;}for (int j = 0; j < 8; j++) {//尝试在第i行的第j列的位置上放置一个皇后if (columnStates[j]==0&&mainDiagStates[i-j+7]==0&&countDiagStates[i+j]==0){//检查是否满足3个条件//在该坐标(i,j)上安放一个皇后,并修改对应的标记数组chessBoard[i][j] = 1;columnStates[j] = 1;mainDiagStates[i - j + 7] = 1;countDiagStates[i + j] = 1;//尝试在下一行(i+1)放置一个皇后,递归调用eightQueens(i + 1);//重置chessBoard[i][j] = 0;columnStates[j] = 0;mainDiagStates[i - j + 7] = 0;countDiagStates[i + j] = 0;}}}int main() {memset(chessBoard, 0, sizeof(int) * 8 * 8);memset(columnStates, 0, sizeof(int) * 8);memset(mainDiagStates, 0, sizeof(int) * 15);memset(countDiagStates, 0, sizeof(int) * 15);planCount = 0;eightQueens(0);cout << "程序完成,共 " << planCount<<" 种方案!" << endl;_sleep(20000);return 0;}

0 0