八皇后问题求解

〖问题描述〗
在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相冲突(在每一横列竖列斜列只有一个皇后)。

        这里我是用回溯法来实现的,存储方式采用的是孩子兄弟表示法。即将一般的数改用二叉树的形式来存储,左子树指向第一个孩子节点,右子树指向第一个兄弟节点。

        因为用递归思路比较简单,我就直接帖代码了。

       QueenTree是整个树的类,Node是每个节点的类。

// QueenTree.h

class  QueenTree
{
public :
         QueenTree();
    
         
void  Build();
         
void  Display();
private :
         
class  Node
         {
          
public :
                     Node();
                     Node(Node
* );
    
                    
bool  IsValid( int );
                    
void  Print();
          
private :
                     friend 
class  QueenTree;
                     
int  chesses[ 8 ];
                     
bool  valid;
            
                     Node
*  child;
                     Node
*  sibling;    
                     
int  rowindex;
           }
* head;
    
private :
          
void  _Build(Node *& , int , int ,Node * );
          
void  _Display(Node * );    
};

         其中chesses[i]=j 是指第i个棋子放在第i 行第j 列,valid用于说明改节点是否满足条件,rowindex为了输出方便加入的,说明这个节点已放置了几行棋子。

// QueenTree.cpp
#include  < iostream >
#include 
" QueenTree.h "

QueenTree::QueenTree()
{
         head
= new  Node;
}

QueenTree::Node::Node()
{
         
for ( int  i = 0 ;i < 8 ;i ++ )    
                chesses[i]
=- 1 ;
         valid
= true ;
         child
= NULL;
         sibling
= NULL;
         rowindex
=- 1 ;
}

bool  QueenTree::Node::IsValid( int  r)
{
         
for ( int  i = 0 ;i < r;i ++ )    
         {
               
if (chesses[i] == chesses[r])
              {
     valid
= false ;
     
return   false ;
              }
              
if ((i - chesses[i]) == (r - chesses[r]))
             {
     valid
= false ;
     
return   false ;
             }
             
if ((i + chesses[i]) == (r + chesses[r]))
             {
     valid
= false ;
     
return   false ;
              }
         }
         valid
= true ;
         
return   true ;
}

void  QueenTree::Build()
{
         _Build(head,
- 1 , - 1 ,NULL);
}

void  QueenTree::_Build(Node *   & t, int  r, int  c,Node *  father)
{
         
if (t == head)
        {
               _Build(t
-> child,r + 1 ,c + 1 ,t);
        }
        
else
       {
                t
= new  Node(father);        
                t
-> chesses[r] = c;
                
if (r < 7 )
                {
          
if (t -> IsValid(r))        
                  _Build(t
-> child,r + 1 , 0 ,t);        
          
else
                   t
-> child = NULL;    
                 }
                 
else
                {
          t
-> IsValid(r);
          t
-> child = NULL;
                 }
                 
if (c < 7 )
          _Build(t
-> sibling,r,c + 1 ,father);
                 
else
          t
-> sibling = NULL;        
         }
}

QueenTree::Node::Node(Node
*  father)
{    
        
bool  flag = false ;
        
for ( int  i = 0 ;i < 8 ;i ++ )    
        {
              
if (father -> chesses[i] ==- 1 &&! flag)
             {
     rowindex
= i;
     flag
= true ;
             }            
             chesses[i]
= father -> chesses[i];        
        }    
         valid
= true ;
         child
= NULL;
         sibling
= NULL;
}

void  QueenTree::Display()
{
        _Display(head);
}

void  QueenTree::_Display(Node *  t)
{
        
if (t -> rowindex == 7   &&  t -> valid)
               t
-> Print();
        
if (t -> child)
              _Display(t
-> child);
        
if (t -> sibling)
              _Display(t
-> sibling);
}

void  QueenTree::Node::Print()
{
        
static   int  count = 0 ;
        std::cout
<< " No. " << count ++<< " " ;
        
for ( int  i = 0 ;i < 8 ;i ++ )
               std::cout
<< " ( " << i << " , " << chesses[i] << " " ;
        std::cout
<< std::endl;
}

        Node有两个构造函数,一个用于建立根节点,一个是建立其余节点,因为非根节点要将它双亲节点的棋子放置拷贝到自己里面,所以加了一个father指针。

// The Test File
#include  " QueenTree.h "

int  main()
{
       QueenTree
*  t = new  QueenTree;
        t
-> Build();
        t
-> Display();
}

      八皇后问题共有92组解,也在下面:( i , j ) 表示棋子放在i 行j 列

No.0: (0,0) (1,4) (2,7) (3,5) (4,2) (5,6) (6,1) (7,3)
No.1: (0,0) (1,5) (2,7) (3,2) (4,6) (5,3) (6,1) (7,4)
No.2: (0,0) (1,6) (2,3) (3,5) (4,7) (5,1) (6,4) (7,2)
No.3: (0,0) (1,6) (2,4) (3,7) (4,1) (5,3) (6,5) (7,2)
No.4: (0,1) (1,3) (2,5) (3,7) (4,2) (5,0) (6,6) (7,4)
No.5: (0,1) (1,4) (2,6) (3,0) (4,2) (5,7) (6,5) (7,3)
No.6: (0,1) (1,4) (2,6) (3,3) (4,0) (5,7) (6,5) (7,2)
No.7: (0,1) (1,5) (2,0) (3,6) (4,3) (5,7) (6,2) (7,4)
No.8: (0,1) (1,5) (2,7) (3,2) (4,0) (5,3) (6,6) (7,4)
No.9: (0,1) (1,6) (2,2) (3,5) (4,7) (5,4) (6,0) (7,3)
No.10: (0,1) (1,6) (2,4) (3,7) (4,0) (5,3) (6,5) (7,2)
No.11: (0,1) (1,7) (2,5) (3,0) (4,2) (5,4) (6,6) (7,3)
No.12: (0,2) (1,0) (2,6) (3,4) (4,7) (5,1) (6,3) (7,5)
No.13: (0,2) (1,4) (2,1) (3,7) (4,0) (5,6) (6,3) (7,5)
No.14: (0,2) (1,4) (2,1) (3,7) (4,5) (5,3) (6,6) (7,0)
No.15: (0,2) (1,4) (2,6) (3,0) (4,3) (5,1) (6,7) (7,5)
No.16: (0,2) (1,4) (2,7) (3,3) (4,0) (5,6) (6,1) (7,5)
No.17: (0,2) (1,5) (2,1) (3,4) (4,7) (5,0) (6,6) (7,3)
No.18: (0,2) (1,5) (2,1) (3,6) (4,0) (5,3) (6,7) (7,4)
No.19: (0,2) (1,5) (2,1) (3,6) (4,4) (5,0) (6,7) (7,3)
No.20: (0,2) (1,5) (2,3) (3,0) (4,7) (5,4) (6,6) (7,1)
No.21: (0,2) (1,5) (2,3) (3,1) (4,7) (5,4) (6,6) (7,0)
No.22: (0,2) (1,5) (2,7) (3,0) (4,3) (5,6) (6,4) (7,1)
No.23: (0,2) (1,5) (2,7) (3,0) (4,4) (5,6) (6,1) (7,3)
No.24: (0,2) (1,5) (2,7) (3,1) (4,3) (5,0) (6,6) (7,4)
No.25: (0,2) (1,6) (2,1) (3,7) (4,4) (5,0) (6,3) (7,5)
No.26: (0,2) (1,6) (2,1) (3,7) (4,5) (5,3) (6,0) (7,4)
No.27: (0,2) (1,7) (2,3) (3,6) (4,0) (5,5) (6,1) (7,4)
No.28: (0,3) (1,0) (2,4) (3,7) (4,1) (5,6) (6,2) (7,5)
No.29: (0,3) (1,0) (2,4) (3,7) (4,5) (5,2) (6,6) (7,1)
No.30: (0,3) (1,1) (2,4) (3,7) (4,5) (5,0) (6,2) (7,6)
No.31: (0,3) (1,1) (2,6) (3,2) (4,5) (5,7) (6,0) (7,4)
No.32: (0,3) (1,1) (2,6) (3,2) (4,5) (5,7) (6,4) (7,0)
No.33: (0,3) (1,1) (2,6) (3,4) (4,0) (5,7) (6,5) (7,2)
No.34: (0,3) (1,1) (2,7) (3,4) (4,6) (5,0) (6,2) (7,5)
No.35: (0,3) (1,1) (2,7) (3,5) (4,0) (5,2) (6,4) (7,6)
No.36: (0,3) (1,5) (2,0) (3,4) (4,1) (5,7) (6,2) (7,6)
No.37: (0,3) (1,5) (2,7) (3,1) (4,6) (5,0) (6,2) (7,4)
No.38: (0,3) (1,5) (2,7) (3,2) (4,0) (5,6) (6,4) (7,1)
No.39: (0,3) (1,6) (2,0) (3,7) (4,4) (5,1) (6,5) (7,2)
No.40: (0,3) (1,6) (2,2) (3,7) (4,1) (5,4) (6,0) (7,5)
No.41: (0,3) (1,6) (2,4) (3,1) (4,5) (5,0) (6,2) (7,7)
No.42: (0,3) (1,6) (2,4) (3,2) (4,0) (5,5) (6,7) (7,1)
No.43: (0,3) (1,7) (2,0) (3,2) (4,5) (5,1) (6,6) (7,4)
No.44: (0,3) (1,7) (2,0) (3,4) (4,6) (5,1) (6,5) (7,2)
No.45: (0,3) (1,7) (2,4) (3,2) (4,0) (5,6) (6,1) (7,5)
No.46: (0,4) (1,0) (2,3) (3,5) (4,7) (5,1) (6,6) (7,2)
No.47: (0,4) (1,0) (2,7) (3,3) (4,1) (5,6) (6,2) (7,5)
No.48: (0,4) (1,0) (2,7) (3,5) (4,2) (5,6) (6,1) (7,3)
No.49: (0,4) (1,1) (2,3) (3,5) (4,7) (5,2) (6,0) (7,6)
No.50: (0,4) (1,1) (2,3) (3,6) (4,2) (5,7) (6,5) (7,0)
No.51: (0,4) (1,1) (2,5) (3,0) (4,6) (5,3) (6,7) (7,2)
No.52: (0,4) (1,1) (2,7) (3,0) (4,3) (5,6) (6,2) (7,5)
No.53: (0,4) (1,2) (2,0) (3,5) (4,7) (5,1) (6,3) (7,6)
No.54: (0,4) (1,2) (2,0) (3,6) (4,1) (5,7) (6,5) (7,3)
No.55: (0,4) (1,2) (2,7) (3,3) (4,6) (5,0) (6,5) (7,1)
No.56: (0,4) (1,6) (2,0) (3,2) (4,7) (5,5) (6,3) (7,1)
No.57: (0,4) (1,6) (2,0) (3,3) (4,1) (5,7) (6,5) (7,2)
No.58: (0,4) (1,6) (2,1) (3,3) (4,7) (5,0) (6,2) (7,5)
No.59: (0,4) (1,6) (2,1) (3,5) (4,2) (5,0) (6,3) (7,7)
No.60: (0,4) (1,6) (2,1) (3,5) (4,2) (5,0) (6,7) (7,3)
No.61: (0,4) (1,6) (2,3) (3,0) (4,2) (5,7) (6,5) (7,1)
No.62: (0,4) (1,7) (2,3) (3,0) (4,2) (5,5) (6,1) (7,6)
No.63: (0,4) (1,7) (2,3) (3,0) (4,6) (5,1) (6,5) (7,2)
No.64: (0,5) (1,0) (2,4) (3,1) (4,7) (5,2) (6,6) (7,3)
No.65: (0,5) (1,1) (2,6) (3,0) (4,2) (5,4) (6,7) (7,3)
No.66: (0,5) (1,1) (2,6) (3,0) (4,3) (5,7) (6,4) (7,2)
No.67: (0,5) (1,2) (2,0) (3,6) (4,4) (5,7) (6,1) (7,3)
No.68: (0,5) (1,2) (2,0) (3,7) (4,3) (5,1) (6,6) (7,4)
No.69: (0,5) (1,2) (2,0) (3,7) (4,4) (5,1) (6,3) (7,6)
No.70: (0,5) (1,2) (2,4) (3,6) (4,0) (5,3) (6,1) (7,7)
No.71: (0,5) (1,2) (2,4) (3,7) (4,0) (5,3) (6,1) (7,6)
No.72: (0,5) (1,2) (2,6) (3,1) (4,3) (5,7) (6,0) (7,4)
No.73: (0,5) (1,2) (2,6) (3,1) (4,7) (5,4) (6,0) (7,3)
No.74: (0,5) (1,2) (2,6) (3,3) (4,0) (5,7) (6,1) (7,4)
No.75: (0,5) (1,3) (2,0) (3,4) (4,7) (5,1) (6,6) (7,2)
No.76: (0,5) (1,3) (2,1) (3,7) (4,4) (5,6) (6,0) (7,2)
No.77: (0,5) (1,3) (2,6) (3,0) (4,2) (5,4) (6,1) (7,7)
No.78: (0,5) (1,3) (2,6) (3,0) (4,7) (5,1) (6,4) (7,2)
No.79: (0,5) (1,7) (2,1) (3,3) (4,0) (5,6) (6,4) (7,2)
No.80: (0,6) (1,0) (2,2) (3,7) (4,5) (5,3) (6,1) (7,4)
No.81: (0,6) (1,1) (2,3) (3,0) (4,7) (5,4) (6,2) (7,5)
No.82: (0,6) (1,1) (2,5) (3,2) (4,0) (5,3) (6,7) (7,4)
No.83: (0,6) (1,2) (2,0) (3,5) (4,7) (5,4) (6,1) (7,3)
No.84: (0,6) (1,2) (2,7) (3,1) (4,4) (5,0) (6,5) (7,3)
No.85: (0,6) (1,3) (2,1) (3,4) (4,7) (5,0) (6,2) (7,5)
No.86: (0,6) (1,3) (2,1) (3,7) (4,5) (5,0) (6,2) (7,4)
No.87: (0,6) (1,4) (2,2) (3,0) (4,5) (5,7) (6,1) (7,3)
No.88: (0,7) (1,1) (2,3) (3,0) (4,6) (5,4) (6,2) (7,5)
No.89: (0,7) (1,1) (2,4) (3,2) (4,0) (5,6) (6,3) (7,5)
No.90: (0,7) (1,2) (2,0) (3,5) (4,1) (5,4) (6,6) (7,3)
No.91: (0,7) (1,3) (2,0) (3,2) (4,5) (5,1) (6,6) (7,4)
 

           最后再说一点,这里我是用树的前序遍历来实现回溯的,也可以用栈来模拟。对于这道题也可以用循环来实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值