N皇后问题

  C++老师布置了一道八皇后问题,自己做了几天:用一维数组映射成二维数组作为N*N棋盘,用堆栈实现,相当麻烦而且已经不打算考虑时间复杂度(因为实在是相当复杂了),而且由于是用四皇后做的例子,结果推广的时候不正确,原因应该是成功找到一个结果后完全清空堆栈,没有继续查找。我也不打算再改了,实在太麻烦。

   做这个题目有个小地方要注意:某位置的斜线位置的表示方法是 abs(X[i]-X[k])==abs(i-k)  对角线检查(列与列之差,行与行之差绝对值相等则为同一斜线)

   以下是我参考网上搜的代码http://www.cnblogs.com/three-zone/archive/2011/12/09/NPQ.html,但是它这个用的内存超过了数组下标的限制,而且没有释放使用的内存,当然这只是一些小毛病,我也只是做了一些小修改。


   以下是代码:

///n_queens_problem.cpp
#include<iostream>
#include<cmath>


using namespace std;


bool place(int k,int *X)
{
    int i;
    i=0;
    while(i<k)            //只需检查k行之前的行,k行之后的行还没有放
    {
       if((X[i]==X[k])||(abs(X[i]-X[k])==abs(i-k)))   //X[i]==X[k]表示列检查;abs(X[i]-X[k])==abs(i-k)表示对角线检查(列与列之差,行与行之差绝对值相等则为同一斜线)
           return false;
       i++;
    }
    return true;
}

/*k*/
int nQueens(int n,int* X)
{
      int k,sum=0;
    X[0]=-1;
k=0;
    while(k>=0)
    {
       X[k]=X[k]+1;              //即便已经找到合适的,X[k]依然加1继续看k行后面的数能否满足
 
       while((X[k]<n)&&(!place(k, X)))   //k行的第几列可以放置
           X[k]=X[k]+1;                      //列数自加
       if(X[k]<n)         //x[k]<=n表示通过以上的检查后这一行如果能放,
           if(k==n-1)        //且这一行已经是最后一行,则输出
           {
         //     for(int i=0;i<n;i++)
           //       cout<<X[i]<<" ";
             // cout<<endl;
              sum++;
           }
           else              //不是最后一行,则进入下一行
           {
              k=k+1;                         //行数自加
              X[k]=-1;
           }
           else         //如果不能放,回到上一行
              k=k-1;
     }
     //cout<<"解的总数为:"<<sum<<endl;
return sum;


}


int main()
{
   cout<<"***********************\n"
  <<"*      n皇后问题      *\n"
  <<"***********************\n";


   cout<<"请输入皇后个数:";
    int n;
   cin>>n;


   cout<<"问题的解决如下:\n";
    int *Chess=new int[n];
   n=nQueens(n,Chess);
   cout<<"结果总数:"<<n<<"\n";
     delete[] Chess;




  return 0;
}


比起我写的要帅气的多,值得学习。

这种方法对于皇后数较大时速度很慢,queens=16时用了半个小时才出来,而位运算的办法只用了不到一分钟

他介绍的另一种方法我没有看完,是用位运算实现的,速度快,以后看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值