八皇后问题求解

〖问题描述〗
在一个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)
 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值