您的位置:首页 > 其它

八皇后问题求解

2007-03-07 16:11 369 查看
〖问题描述〗
在一个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)

最后再说一点,这里我是用树的前序遍历来实现回溯的,也可以用栈来模拟。对于这道题也可以用循环来实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: