八皇后问题

八皇后问题一共有92种不同的摆放方法。按照前面对四皇后问题的讨论,摆放时按行的顺序进行,因此只需考虑列和对角线的问题。

为了讨论皇后问题摆放的可行性,程序中使用到的三个数组C[j] 、R[m]和L[k] 都为布尔型且初始化时全部置为true。其中i为行号,j为列号,i,j=1,2,…8;m=i+j,m=2,3,…16;k=i-j+9,k=2,3,…16。右上至左下的对角线是否可行,取决于R[m]为true或false;而左上至右下的对角线是否可行,取决于L[k]为true或false。这样可以令

L(i-j+9)=false

L(i+j)=true

来表示在(i,j)位置摆放皇后之后,通过该位置的两条对角线上不可行了。这样得出在(i,j)位置可摆放皇后的可行条件是:

nQueen=C[j] &&R[i+j]&&L[i-j+9]

其中i-j+9是为了避免数组下标为负值,再有就是为了使L数组和R数组的下标上下界一致,均为2,3,….,16。

在摆放第i个皇后时(当然在第i行),选择第j列,当nQueen为true时,就可将皇后摆放在(i,j)位置。如果Queen[i]=j,则同时使得第j列和过(i,j)位置的两条对角线变为不可行,即C[j]=false,R[i+j]=false,L[i-j+9]=false;之后检查i是否为8,如果为8则表明已经放完8个皇后,这时让方案数Num加1,输出该方案下8个皇后在棋盘上的位置,如果未到8个,则要让皇后数i加1再尝试摆放,这时递归调用check(i+1);如果方案不可行,则需要回溯,将前面摆放的皇后从棋盘上拿起,看看还有没有可能换一处位置摆放,这时要将被拿起的皇后的所在位置的第j列和两条对角线恢复为可行。

#include<iostream>

using namespace std;

const int Normalize=9;        //定义常量,用来统一数组下标

int Num=0;                //整型变量,记录方案数

int Queen[9];                //记录8个皇后所占用的列号



bool C[9];                    //C[1]~C[8]布尔型变量,判断当前列是否可行

bool L[17];                    //L[2]~L[16]布尔型变量,判断(i-j)对角线是否可行

bool R[17];                //R[2]~R[16]布尔型变量,判断(i+j)对角线是否可行



void check(int i)                //被调用函数

{

    int j;                        //循环变量,表示列号

    int k;                        //临时变量

    for(j=1;j<=8;j++)

    {

        if((C[j]==true) &&(R[i+j]==true)&&(L[i-j+Normalize]==true))

//表示第i行第j列可行

        {

            Queen[i]=j;            //占用位置(i,j)

            C[j]=false;                //修改可行标志,包括所在列和两个对角线

            L[i-j+Normalize]=false;

            R[i+j]=false;

            if(i<8)                //判断是否放完8个皇后

            {

                check(i+1);    //未放完8个皇后则继续放下一个

            }

            else                    //已经放完8个皇后

            {

                Num++;        //方案数加1

                cout<<"方案"<<Num<<":"<<"\t";//输出方案号

                for(k=1;k<=8;k++)

                    cout<<k<<"行"<<Queen[k]<<"列"<<"\t";//输出具体方案

                cout<<endl;    //换行

            }

            C[j]=true;                //修改可行标志,回溯

            L[i-j+Normalize]=true;

            R[i+j]=true;

        }                        //循环结束

    }

}                        //check函数结束



int main()                    //主函数

{

    int i;                        //循环变量

    Num=0;                    //方案数清零

    for(i=1;i<9;i++)                //置所有列可行

        C[i]=true;

    for(i=0;i<17;i++)            //置所有对角线可行

        L[i]=R[i]=true;

    check(1);                    //递归放置8个皇后,从第一行开始放

    return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计科小宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值