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;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值