Exercise(6):八皇后

/* 八皇后 问题描述: 在一个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;
        }
    }
}

你可能感兴趣的:(蓝桥)