八皇后问题 回溯法

八皇后:西洋棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstra与N.Wirth曾经用这个问题来讲解程序设计的结构性编程技巧。

在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上

解法:关于棋盘的问题,都可以用递回求解,然而如何减少递回的次数?在八个皇后的问题中,不必要所有的格子都检查过,例如若某列检查过(已被放置),该该列的其它格子就不用再检查了,这个方法称为剪支。显然,每一行可以而且必须放一个皇后,所以n皇后问题的解可以用一个n元向量X=(x1,x2,.....xn)表示,其中,1 i n且1 xi n,即第n个皇后放在第i行第xi列上。

由于两个皇后不能放在同一列上,所以,解向量X必须满足的约束条件为:

xi xj;

若两个皇后的摆放位置分别是(i,xi)和(j,xj),在棋盘上斜率为-1的斜线上,满足条件i-j=xi-xj;在棋盘上斜率为1的斜线上,满足条件i+j=xi+xj;

综合两种情况,由于两个皇后不能位于同一斜线上,所以,

解向量X必须满足的约束条件为:

|i-xi| |j-xj|

#include <iostream>
#include <string>

using namespace std;

int x[8];

bool place(int k)
{
	int i;
	for(i=1;i<k;i++)
		if(x[k]==x[i] || abs(k-i)==abs(x[k]-x[i]))
			return false;
	return true;
}

void queue()
{
	int i,k;
	for(i=1;i<=8;i++)
		x[i]=0;
	k=1;
	while (k>=1)
	{
		x[k]=x[k]+1;      //在下一列放置第k个皇后
		while(x[k]<=8&&!place(k))
            x[k]=x[k]+1;        //搜索下一列
		if(x[k]<=8&&k==8)//得到一个输出
        {
            for(i=1;i<=8;i++)
                cout<<x[i]<<"   ";
			cout<<endl;          //若return则只求出其中一种解,若不return则可以继续回溯,求出全部的可能的解
        }
		else if (x[k]<=8 && k<8)
		{
			k++;
		}
		else
		{
			x[k]=0;
			k--;
		}
	}
}

int main()
{
	cout<<"皇后位置: "<<endl;
	queue();
	system("pause");
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值