(1)问题重述:
在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?
(2)代码实现:(看不懂在说,应该看得懂啊!都有注释的说)
/*******************首先是给出的main程序的入口***********************/
// 八皇后.cpp : 定义控制台应用程序的入口点。
#include"stdafx.h" //在建项目的时候让编译器自动预编译的
#include"EightQueens.h"
#include<iostream> //调用运行空间
using namespace std; //避免冲突
int _tmain(int argc,_TCHAR* argv[])
{
EightQueens Queens; //建立一个实例
Queens.Init(); //初始化实例对象
Queens.SearchSolution(8);
return 0;
}
/********************EightQueen.h中对类的定义*********************/
#pragma once //避免重复的引用
classEightQueens //对类的定义
{
public:
EightQueens(void);//构造函数
~EightQueens(void);// 析构函数
public:
voidInit(); //初始化函数
voidSearchSolution(unsigned int Count); //解决方案函数
private:
voidOutput();//输出函数
private:
int* m_Pos; //当前皇后的位置
int m_Count; //皇后个数
int* m_Sign[3]; //皇后标志位1有,0无
};
/************EightQueen.cpp对EightQuenn,h中的定义实现***************/
#include "StdAfx.h"
#include "EightQueens.h"
#defineQUEEN_COUNT (8)
EightQueens::EightQueens(void)
:m_Pos(NULL)
,m_Count(0)
{
m_Sign[0] = NULL;
m_Sign[1] = NULL;
m_Sign[2] = NULL;
}
EightQueens::~EightQueens(void)
{
for (int i=0;i<3;i++)
{
if(m_Sign[i] != NULL)
{
delete[]m_Sign[i];
m_Sign[i] = NULL;
}
}
if (m_Pos!= NULL)
{
delete[]m_Pos;
m_Pos = NULL;
}
}
voidEightQueens::Init()//分配标志位的内存空间
{
m_Sign[0] = newint[QUEEN_COUNT+1];
m_Sign[1] = newint[2*QUEEN_COUNT+1];//强调是两倍的长度
m_Sign[2] = newint[2*QUEEN_COUNT+1];
m_Pos = newint[QUEEN_COUNT+1];
//初始值为true,表示可以放(1→true;0→false。这就不用解释了吧)
for ( int i = 0; i != QUEEN_COUNT+1; i++)
{
m_Pos[i] = 0;
m_Sign[0][i] = 1;
}
for ( int i = 0; i != 2*QUEEN_COUNT+1; i++)
{
m_Sign[1][i] = 1;
m_Sign[2][i] = 1;
}
}
voidEightQueens::SearchSolution(unsigned int Count)
{
for (int i=1;i!=QUEEN_COUNT+1;i++)
{
if(m_Sign[0][i] && m_Sign[1][i + Count] && m_Sign[2][Count - i +QUEEN_COUNT]) //判断当前皇后是否安全
{ /*m_Sign[0][i]保证不在同一列;m_Sign[1][i+ Count]保证当前皇后不上前一
个Queen的斜率成1;m_Sign[2][Count- i + QUEEN_COUNT]保证当前皇后不上前一个Queen的斜率成-1;前8个单元放的是上一个Queende位置,后八个是当前的。如果还是想不通话,你就把后8个单元看成是二维数组中的array[1]就明白了。*/
m_Sign[0][i] =m_Sign[1][i + Count] = m_Sign[2][Count - i + QUEEN_COUNT] = 0;
m_Pos[Count] = i; //安全的话,记录位置。
if( 1 == Count ) //若是最后一个皇后的话即是找到找了第一个解,输出。
{
m_Count ++;
Output();
}
else//若不是最后一个皇后,向下判断剩下的Count-1个Queens. {
SearchSolution(Count- 1);
}
//回溯到上一个Queens,i++表示尝试下一个安全位置,解next解。 m_Sign[0][i] = m_Sign[1][i+ Count] = m_Sign[2][Count - i + QUEEN_COUNT] = 1;
}
}
}
voidEightQueens::Output()
{
cout<<"第"<<m_Count<<"组解:\t";
for (int i=QUEEN_COUNT;i!=0;i--)
{
cout<<m_Pos[i]<<"\t";
}
cout<<endl;
}