郁结多日之后,突然想到了这种方法,个人以为还是比较独特的。此算法最大的特点就是较为巧妙地运用了递归和堆栈,在尽量降低时间复杂度的同时,将空间复杂度降到了最低(长度不超过m的堆栈)。
先简单介绍一下八皇后问题,一下摘自百度百科:“该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。”
下面附上代码,与大家分享一下,也欢迎各位大牛的批评指教。
人生第一篇博客,谨以此文纪念。
#include<iostream>
using namespace std;
const int m = 8;//行数
const int n = 8;//列数
class queen //皇后类
{
public:
int x; //皇后所在行
int y; //皇后所在列
queen* next;
queen()
{
x = -1;
y = -1;
next = NULL;
}
};
class chess
{
public:
queen* head;
void put(int, int);
void pop();
void display();
bool check_queens(int, int); //检查是否冲突
chess()
{
head = NULL;
head = new queen;
head->x = -1;
head->y = -1;
head->next = NULL;
}
};
chess ch;
int ni = 0;
void find_queens(int);
void main()
{
find_queens(0);
}
void find_queens(int m1)
{
if (m1 == m)
{
ch.display();
}
if (m1 >= m)
return;
int i;
for (i = 0; i < n; i++) //遍历该行上每一个位置
{
if (!ch.check_queens(m1, i))
continue;
else
{
ch.put(m1, i); //若不冲突将次位置放置皇后,即将该位置入栈
find_queens(m1 + 1); //在此基础上递归寻找下一行的皇后
ch.pop();//(m,i) pop; //移除该皇后,寻找该行是否存在其它位置也可放置皇后
}
}
return;
}
bool chess::check_queens(int x, int y)
{
queen* q = NULL;
q = new queen;
q = head->next;
while (q != NULL)
{
if (q->x == x) //检查同行
return false;
if (q->y == y) //检查同列
return false;
if (abs(q->x - x) == abs(q->y - y)) //检查交叉线
return false;
q = q->next;
}
return true;
}
void chess::put(int x, int y) //入栈
{
queen* q = NULL;
q = new queen;
q->x = x;
q->y = y;
q->next = head->next;
head->next = q;
}
void chess::pop() //出栈
{
queen* q = NULL;
q = new queen;
q = head->next;
head->next = q->next;
delete q;
}
void chess::display() //显示
{
queen* show = NULL;
show = new queen;
show = head->next;
while (show != NULL)
{
cout << "(" << show->x << ", " << show->y << ") ";
show = show->next;
}
cout <<++ni<< endl;
}