n皇后问题求解

       八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法

     下面利用栈来求解。

#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#define MaxSize 100

typedef int data;

typedef struct  
{  
    int data[MaxSize];  //data[i]存放第i个皇后的列号  
    int top;            //栈顶指针  
} StNode;               //定义顺序栈类型  

/**********************初始化栈**********************/
void InitStack(StNode *&s)
{
	s = new StNode;
	s->top = 0;;
}

/**********************销毁栈********************/
void DestroyStack(StNode *&s)
{
	free (s);
}

/******************判断栈是否为空*******************/
bool StackEmpty(StNode *s)
{
	return (0 == s->top);
}

/********************进栈****************/
bool Push(StNode *&s, data e)
{
	if (MaxSize -1 == s->top)
		return false;
	s->top++;
	s->data[s->top] = e;
	return true;
}

/**********************出栈*******************/
bool Pop(StNode *&s, data &e)
{
	if (0 == s->top)
		return false;
	e = s->data[s->top];
	s->top--;
	return true;
}

/***************判断是否可以放下皇后*************/
bool IsPlace(StNode *s, int i, int j)
{
	int k = 1;
	if (i == 1)		//第一个皇后
		return true;
	while (k < i)		//遍历已放下的皇后
	{
		if ((s->data[k]==j)||(fabs(j-s->data[k])==fabs(i-k)))		//判断是否同行或斜线
			return false;
		else
			k++;
	}
	return true;
}

void PrintEightQueen(StNode *s,int n,int &sum)
{
	
		cout<<"第"<<++sum<<"个解:  ";
		for (int k = 1; k <= s->top; k++)
		{
			cout<<"("<<k<<","<<s->data[k]<<")  ";
		}
		cout<<endl;
		for (int x = 1; x <= n; x++)
		{
			for (int y = 1; y <=  n; y++)
			{
				if (s->data[x] == y)
					cout<<"Ж";
				else
					cout<<"□";
			}
			cout<<endl;
		}
		cout<<endl;
}

/**************求解皇后**************/
void EightQueen(StNode *&s,int n)
{
	int sum = 0;
	data e;
	Push(s,1);		//(1,1)进栈
	int i;
	int j;
	int put = 0;		
	while (!StackEmpty(s))
	{
		i = s->top;
		if (s->top == n)		//所有皇后都找到
		{
			PrintEightQueen(s,n,sum);
		}
		put = 0;
		for (j = 1; j <= n; j++)	//查找当前行可放下的位置
		{
			if (IsPlace(s,i+1,j))		//可放下进栈
			{
				e = j;
				Push(s,e);
				put = 1;
				break;
			}
		}
		if (0 == put)		//找不到
		{
			while (!StackEmpty(s))
			{
				Pop(s,e);
				while (++e <= n)	//查找退栈当行的的下一个位置是否可放下皇后
				{
					if(IsPlace(s,s->top+1,e))
					{
						Push(s,e);
						put = 1;
						break;
					}
				}
				if (put)
					break;
			}
		}
	}

}

void main()
{
	int num;
	cout<<"请输入要n皇后问题(n):";
	cin>>num;
	StNode *s;
	InitStack(s);
	EightQueen(s,num);
	DestroyStack(s);

}


猜你喜欢

转载自blog.csdn.net/weixin_37267014/article/details/78393350
今日推荐