回溯_8皇后

八皇后是国际象棋中最大的棋子,要使得放置N个皇后在N*N的棋盘上,使其不能互相攻击


皇后攻击范围:其同行,同列 以及其斜对角。



回溯法,把一个皇后放在某行的第一列,然后检查它是否与棋盘上的其他皇后互相攻击,如果存在互相攻击,函数把皇后移动到该行的第二列再进行检查,如果每列都存在相互攻击的局面,函数就该返回。

但是如果皇后可以放在这个位子,函数借着应该递归地调用自身,把一个皇后放在下一行,当递归调用返回时,函数再把原先那个皇后移到下一列。当皇后成功地放置于最后一行时,打印出棋盘,显示8个皇后的位子。



#include<stdio.h>
#include <math.h>

#define Num_Queen 8//这里定义为8个皇后 可任意修改
int state[Num_Queen];//第M行的第几个位有皇后,例如state[4]=3;表示第四行第三列有皇后;
int sum = 0;

//判断各个皇后大人是否相互攻击
int attack( int n)
{
	for(int i =0;i<n;i++)
	{
		if(state[i] == state[n])//判断是否在同一列
		{
			return 0;
		}
		if(abs(state[n]-state[i])==abs(n-i))//判断是否在对角线
		{
			return 0;
		}
	}
	return 1;
}

//打印棋盘,有皇后的位置打印出“*”,空格则打印“#”
void  output()
{
    for(int i = 0;i<Num_Queen;i++)
	{
		for(int j = 0;j<Num_Queen;j++)
		{
			if(j == state[i])
			{
				printf("*");
			}
			else
			{
				printf("#");
			}
		}
		printf("\n");
	}
	printf("\n\n");
}
//回溯函数,递归放置N个皇后
void  queen(int n)
{
	if(n == Num_Queen)//如果8个皇后都放好切不互相攻击的话,将它输出并回溯
	{ 
		sum++;//计算共有多少种放置方法
		output();
		return;
	}
	for(int i = 0;i<Num_Queen;i++)
	{
		state[n] = i;//在n行i列上放置皇后
		if(attack(n)) //如果没有互相攻击的话,则进行下一行的试探
		{
			queen(n+1);
		}
	}
}

int main()
{
	queen(0);//从第0行开始递归
	printf("%d\n",sum);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/blackholeAC/article/details/6960526