风言枫语  

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。


方法一:递归实现

方法二:迭代实现

方法三:利用全排列递归实现

实现代码如下:

 

#include<iostream>
#include<cmath>
using namespace std;
bool place(int *Q,int len,int index);
bool check(int *Q,int len);
void Queue1(int *Q,int len,int index);
void Queue2(int *Q,int len);
void Queue3(int *Q,int len,int index);
int main()
{
	int len;
	cin>>len;//输入皇后的个数
	int *Q=new int[len+1];//Q[0]暂不使用
	cout<<"method1:"<<endl;
	Queue1(Q,len,1);
	cout<<"method2:"<<endl;
	Queue2(Q,len);
	cout<<"method3:"<<endl;
	for(int i=1;i<=len;i++)
		Q[i]=i;
	Queue3(Q,len,1);
	delete []Q;
	return 0;
}
///////////////////////////////////////////////////////////////////////////////////
bool place(int *Q,int len,int index)
{
	int i;
    for(i=1;i<index;i++)
	{
        if(Q[index]==Q[i]||abs(index-i)==abs(Q[index]-Q[i]))
            return false;
	}
    return true;
}
//递归实现
void Queue1(int *Q,int len,int index)
{
	if(Q==NULL||len<=0)
		return;
	if(index>len)
	{
		static int num1=1;
		cout<<num1++<<":";
		for(int i=1;i<=len;i++)
			cout<<Q[i]<<" ";
		cout<<endl;
	}
	else
	{
		for(int i=1;i<=len;i++)
		{
			Q[index]=i;
			if(place(Q,len,index))
				Queue1(Q,len,index+1);
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////
//非递归实现
void Queue2(int *Q,int len)
{
	int i,k;
    for(i=1;i<=len;i++)
        Q[i]=0;
    k=1;
    while(k>=1)
    {
        Q[k]=Q[k]+1;   //在下一列放置第k个皇后
        while(Q[k]<=len&&!place(Q,len,k))
            Q[k]=Q[k]+1;//搜索下一列
        if(Q[k]<=len&&k==len)//得到一个输出
        {
			static int num2=1;
			cout<<num2++<<":";
            for(i=1;i<=len;i++)
                cout<<Q[i]<<" ";
            cout<<endl;
        }
        else if(Q[k]<=len&&k<len)
            k=k+1;//放置下一个皇后
        else
        {
            Q[k]=0;//重置Q[k],回溯
            k=k-1;
        }
    }
}
/////////////////////////////////////////////////////////////////////////////////////
//检查全排列是否符合摆放要求
bool check(int *Q,int len)
{
	for(int i=1;i<=len;i++)
    {
        for(int j=i+1;j<=len;j++)
        {
            if(abs(j-i)==abs(Q[j]-Q[i]))
				return false;
        }
	}
	return true;
}
//利用全排列实现
void Queue3(int *Q,int len,int index)
{
	if(Q==NULL||len<=0)
		return;
    if(index>len)
    {
        if(check(Q,len))//对生成每个全排列进行检查,若符合要求则输出
        {
            static int num3=1;
			cout<<num3++<<":";
			for(int i=1;i<=len;i++)
				cout<<Q[i]<<" ";
			cout<<endl;
        }
    }
    else
    {
        for(int i=index;i<=len;i++)
        {
            int temp=Q[i];
            Q[i]=Q[index];
            Q[index]=temp;

			Queue3(Q,len,index+1);

			temp=Q[index];
            Q[index]=Q[i];
            Q[i]=temp;
        }
    }
}


 


 

posted on 2013-09-12 22:52  风言枫语  阅读(163)  评论(0编辑  收藏  举报