用回溯法和栈来八皇后问题

heidongfeng 2009-04-14 09:56:43
在数据结构课程设计中,本人急求解决八皇后问题。
课程设计要求如下:
在实际应用中,有相当一类问题需要找出它的解集合,或者要求找出某些约束条件
下的最优解。求解时经常使用一种称为回溯的方法来解决。所谓回溯就是走回头路,该
方法是在一定的约束条件下试探地搜索前进,若前进中受阻,则回头另择通路继续搜索。
为了能够沿着原路逆序回退,需用栈来保存曾经到达的每一个状态,栈顶的状态即为回
退的第一站,因此回溯法均可利用栈来实现。而解决八皇后问题就是利用回溯法和栈来
实现的。

八皇后问题是在8x8的国际象棋棋盘上,安放8个皇后,要求没有一个皇后能够“吃
掉”任何其他一个皇后,即没有两个或两个以上的皇后占据棋盘上的同一行、同一列或
同一条对角线。
八皇后在棋盘上分布的各种可能的格局,其数目非常大,约等于232种,但是,可以
将一些明显不满足问题要求的格局排除掉。由于任意两个皇后不能同行,即每一行只能
放置一个皇后,因此将第i个皇后放置在第i行上。这样在放置第i个皇后时,只要考虑它
与前i一1个皇后处于不同列和不同对角线位置上即可。因此,其算法基本思想如下:
从第1行起逐行放置皇后,每放置一个皇后均需要依次对第1,2,…,8列进行试探,
并尽可能取小的列数。若当前试探的列位置是安全的,即不与已放置的其他皇后冲突,
则将该行的列位置保存在栈中,然后继续在下一行上寻找安全位置;若当前试探的列位
置不安全,则用下一列进行试探,当8列位置试探完毕都未找到安全位置时,就退栈回
溯到上一行,修改栈顶保存的皇后位置,然后继续试探。
...全文
649 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
heidongfeng 2009-12-17
  • 打赏
  • 举报
回复
哦,谢谢二楼
测试菜鸟 2009-09-15
  • 打赏
  • 举报
回复
看看
forster 2009-09-15
  • 打赏
  • 举报
回复
代码短不见得算的快 现在内存那么便宜,敲一辈子代码顶多100块钱的内存。。
hljhnu 2009-09-15
  • 打赏
  • 举报
回复
此代码确实太长了!!
Paradin 2009-04-14
  • 打赏
  • 举报
回复
见过几行代码搞定八皇后的
baihacker 2009-04-14
  • 打赏
  • 举报
回复
#include	<iostream>
#include <windows.h>
using namespace std;


const int MAX_QUEEN = 16;
int key[MAX_QUEEN];
int collock[MAX_QUEEN][MAX_QUEEN];
int showkey;//是否显示解

int Place1 (int k, int i);
void NQueens1(int k, int n);
int Place2 (int start, int k, int n);
void NQueens2(int k, int n);
void show(int n);

inline int ABS(int n)
{
return n > 0 ? n : -n;
}

int main()
{
showkey = 0;

cout<<"皇后数在13的时候算法1需要时间40秒左右"<<endl;
cout<<"如果时间不允许请把main函数中"<<endl;
cout<<"for (int i = 0; i<14; i++)改为"<<endl;
cout<<"for (int i = 0; i<13; i++)"<<endl;
cout<<"皇后数\t算法1\t算法2"<<endl;
for (int i = 0; i<14; i++)
show(i);

return 0;
}

int Place1(int k, int i)
{
for (int j = 0; j<k; j++)
if ( key[j] == i || ABS(key[j]-i) == ABS(j-k))
return 0;
return 1;
}

void NQueens1(int k, int n)
{
for (int i = 0; i<n; i++)
if (Place1(k, i))
{
key[k] = i;
if (k==n-1)
{
if (showkey)
{
for (int j = 0; j<n; j++)
cout<<key[j]+1<<' ';
cout<<endl;
}
}
else
{
NQueens1(k+1, n);
}
}
}

int Place2(int start, int k, int n)
{
for (int i = start + 1; i<n; i++)
if (!collock[k][i])
return i;
return -1;
}

void NQueens2(int k, int n)
{
for (int i = 0; i<n; i++)
collock[k][i] = 0;
for (int i = 0; i<k; i++)
{
int l = ABS(k-i);
collock[k][key[i]] = 1;
if (key[i] - l>=0)
collock[k][key[i] - l] = 1;
if (key[i] + l<n)
collock[k][key[i] + l] = 1;
}

int start = -1;
while ( (start = Place2(start, k, n)) != -1)
{
key[k] = start;
if (k==n-1)
{
if (showkey)
{
for (int j = 0; j<n; j++)
cout<<key[j]+1<<' ';
cout<<endl;
}
}
else
{
NQueens2(k+1, n);
}
}
}

void show(int n)
{
static DWORD stime, etime;

cout<<n<<'\t';

stime = GetTickCount();
NQueens1(0, n);
etime = GetTickCount();
cout<<etime-stime<<"\t";

stime = GetTickCount();
NQueens2(0, n);
etime = GetTickCount();
cout<<etime-stime<<endl;
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧