/*
八皇后
问题描述:
在一个8*8的棋盘上放置8个皇后,不允许任何两个皇后在棋盘的同一行、同一列和同一对角线上
(国际象棋规定皇后可以吃掉同行同列同对角线上的棋子)
问题分析:
经观察发现,对8 x 8的二维数组上的某点a[i][j](0<=i,j<=7)
* 此处可用Excel表格观察规律 *
①每个点a[i][j]的主对角线(即左上至右下)上的值(i-j+8)(范围在[1,15])均相等;
②每个点a[i][j]的从对角线(即右上至左下)上的值(i+j-1)(范围在[1,15])均相等;
因此,通过判断该点的值(i-j+7或 i+j)即可知道该点主对角线上或从对角线上是否已经有皇后。
由于以上两种都由15个数组成(1-15,1-15),固设置两个数组
分别代表各主从对角线上是否有皇后:
Prd[15] * 主对角线(Principal Diagonal) *
Sud[15] * 从对角线(Subordinate Diagonal) *
true 表示有皇后
false 表示无皇后
*/
#include <iostream>
using namespace std;
/* 为了方便,首元素不使用 */
const int QueenCount = 8;
int Num; // 记录方案数
int QueenLocate[QueenCount+1]; // 记录皇后的位置:下标为行,值为列
bool Column[QueenCount+1]; // 判断同列上是否有皇后
bool Prd[2*QueenCount]; // 判断主对角线是否有皇后
bool Sud[2*QueenCount]; // 判断从对角线是否有皇后
void ShowQueenLocate(); // 显示八皇后位置
void SearchQueenLocate(int r); // 寻找八皇后位置
int main()
{ // 初始化
int i;
Num = 0; // 初始化方案数为0
for(i=0;i<=QueenCount;i++)
{
QueenLocate[i] = 0; // 初始化皇后皆无位置(列为0)
Column[i] = false; // 初始化全部行上无皇后
}
for(i=0;i<=2*QueenCount-1;i++) // 初始化各点主从对角线上无皇后
{
Prd[i] = false;
Sud[i] = false;
}
SearchQueenLocate(1); // 从第一行开始
cout<<endl<<"总计有 "<<Num<<" 种方案"<<endl;// 输出方案总数
}
// 显示八皇后位置
void ShowQueenLocate()
{
int row,column;
cout<<endl<<"方案 "<<++Num<<endl;
for(row=1;row<=QueenCount;row++) // 判断皇后所在位置显示为“Q ”,其余为“. ”
{
for(column=1;column<=QueenCount;column++)
{
if(QueenLocate[row]==column)
cout<<"Q"<<ends;
else
cout<<"."<<ends;
}
cout<<endl;
}
}
// 寻找八皇后位置
void SearchQueenLocate(int r)
{
int c;
if(r>QueenCount) // 递归结束条件:参数r(行数)大于皇后总数时,显示八皇后位置
{
ShowQueenLocate();
}
for(c=1;c<=QueenCount;c++)
{
if(Column[c]==false && Prd[r-c+8]==false && Sud[r+c-1]==false)
{ // 符合此3个条件,赋值皇后位置
QueenLocate[r] = c;
// 占用该点行列对角线所有位置
Column[c] = Prd[r-c+8] = Sud[r+c-1] = true;
// 进入下一行
SearchQueenLocate(r+1);
// 递归结束后取消该点占用
Column[c] = Prd[r-c+8] = Sud[r+c-1] = false;
}
}
}
Exercise(6):八皇后
最新推荐文章于 2021-11-29 19:18:03 发布