八皇后问题

/*
问题描述:如何在一个8*8的棋盘上无冲突的摆放8个皇后棋子。要求:皇后棋子所在的位置的水平方向,垂直方向,45度斜线方向都不能出现皇后棋子。
          求出所有符合要求的摆放方法。
解决方法:采用递归的方法。(其他如回溯法,穷举法,概率算法又叫拉斯维加斯算法),用8*8的0—1矩阵表示棋盘,1表示皇后棋子,0代表空。
*/
#include<stdio.h>
int count=0;//记录八皇后问题解的个数

int NotEqual(int row,int col,int (*chess)[8])
{//判断在棋盘chess的row行col列能否摆放皇后棋子,即判断row行 ,col列,其左上角,左下角,右上角,右下角,有没有皇后棋子。
 //如果可以摆放则返回1,否则返回0
	int i,j;
	for(i=0;i<8;i++)//判断row行是否存在皇后棋子
		if(*(*(chess+row)+i))
			return 0;
    for(i=0;i<8;i++)//判断col列是否存在皇后棋子
		if(*(*(chess+i)+col))
			return 0;
	for(i=row,j=col;i>=0&&j>=0;i--,j--)//判断row行col列的左上角是否有皇后棋子
		if(*(*(chess+i)+j))
			return 0;
	for(i=row,j=col;i<8&&j<8;i++,j++)//判断row行col列的右下角是否有皇后棋子
		if(*(*(chess+i)+j))
			return 0;
	for(i=row,j=col;i<8&&j>=0;i++,j--)//判断row行col列的左下角是否有皇后棋子
		if(*(*(chess+i)+j))
			return 0;
	for(i=row,j=col;i>=0&&j<8;i--,j++)//判断row行col列的右上角是否有皇后棋子
		if(*(*(chess+i)+j))
			return 0;
	return 1;
}

void EightQueen(int row,int (*chess)[8])
{//由题意值棋盘的每一行上必存在一个皇后棋子。因此当所有行上都摆放上了皇后棋子,则8个皇后棋子都摆放完成,打印出棋盘。
//否则,采用递归方法,在下一行中找到摆放皇后棋子的位置。
	int chess2[8][8],i,j;
	for(i=0;i<8;i++)//复制棋盘,用作递归使用。递归条件结束,形成符合要求的八皇后棋盘。
		for(j=0;j<8;j++)
			chess2[i][j]=*(*(chess+i)+j);
	if(row==8)//8个皇后棋子都已正确摆放,打印八皇后棋盘
	{
		for(i=0;i<8;i++)
		{
		  for(j=0;j<8;j++)
			printf("%d ",chess2[i][j]);
		  printf("\n");
		}
		printf("\n\n");
		getchar();//作用:每次输出一个棋盘,须在输入任意一个字符才会输出另一个棋盘
		count++;//记录解的个数

	}
	else
	{

		for(j=0;j<8;j++)
		{
			if(NotEqual(row,j,chess))
			{
				for(i=0;i<8;i++)
				   *(*(chess2+row)+i)=0;
				*(*(chess2+row)+j)=1;
				EightQueen(row+1,chess2);
			}
		}
	}
}
int main(void)
{
    int chess[8][8],i,j;
	for(i=0;i<8;i++)
		for(j=0;j<8;j++)
			chess[i][j]=0;
	
	printf("八皇后棋盘分别为:\n\n");
	EightQueen(0,chess);
	printf("八皇后问题解的个数为:%d\n",count);

}

你可能感兴趣的:(算法)