八皇后问题

问题描述:

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。

该问题是19世纪著名的数学家高斯1850年提出:在8×8格的国际象棋上摆放8个皇后,使其不能相互共计,

即任意两个皇后都不能处于同一行、同一列或同一斜线上,

问有多少种摆法?


#include <stdio.h>
#define N 8
int count = 0;                      //答案编号
int queen[N];                       //第i(0<=i<N)行的皇后在queen[i]列                       
int col[N];                         //第i列是否可以放queen,可以为1,否则为0
int lu_to_rd[2*N];                  //左上(leftup)至右下(rightdown)的斜线上是否可以放queen,可以为1,否则为0
int ld_to_ru[2*N];                  //左下(leftdown)至右上是否可以放queen,可以为1,否则为0
void printArray();                  //打印答案
int able(int i,int j);              //第i行第j列是否是否可以放queen,可以返回1,否则返回0
void  recursion(int i);             //从第i行开始递归求解
int main(void)
{
	int i;
	for(i=0;i<N;i++)               //初始化
	{
		 col[i] = 1;
	}
	for(i=0;i<2*N;i++)
	{
		lu_to_rd[i] = ld_to_ru[i] = 1;
	}
	recursion(0);
	return 0;
}

void printArray()
{
	int i,j;
	printf("----------------------------------\n");
	printf("count: %d \n",count++);
	for(i=0;i<N;i++)
	{
		for(j=0;j<8;j++)
		{
			if(queen[i]!=j)
			{
				printf("_");
			}
			else
			{
				printf("Q");                                           //打印queen
			}
			

		}

		printf("\n");
	}
	printf("----------------------------------\n");
}

int able(int i,int j)
{
	if (col[j] == 1 && lu_to_rd[i+j] == 1 && ld_to_ru[i-j-1+N] == 1)   //假如列方向和两个对角线方向上全都可以放queen,
	{                                                                  //就返回1
	    return 1;
	}
	return 0;
}

void  recursion(int a)
{
	int i;
	if(a>=N)                                                    //a >= N 说明已经递归到最后一行,输出答案
	{
		printArray();
		
	}
	else
	{
		for(i=0;i<N;i++)                                      
		{
			if(able(a,i))
			{
				queen[a] = i;                                 //第i列可以放queen
				col[i] = 0;                                   //因为第i列已经放了queen,则要设置该列和两个对角线方向上为0  	
				lu_to_rd[a+i] = ld_to_ru[a-i-1+N] = 0;
				
				recursion(a+1);                               //递归到下一行求解
				
				
				col[i] = 1;                                  //上一层递归结束后要更新第i列的信息
				lu_to_rd[a+i] = ld_to_ru[a-i-1+N] = 1 ;
			}
		}
	}
}

关于两条斜线上的问题:
一、判断问题
其实判断两个点在不在同一条斜线上,就是判断这两个点是不是属于同一条直线;
利用坐标的思想(x + y = b || x - y = c  #两条斜线的倾斜角为45度或135度);
而第i行第j列很容易转换成坐标;例如queen[1] = 2,queen[2] = 1,易得出这两点在同一条斜线上;
二、数组大小问题
8*8的正方形(0,0)(1,0)(0,1).........
会发现由整数点所连起来的倾角为45度的直线一共有13条,但为了判断的方便,我们把(7,0)(0,7)的点也算上;
这样就一共是15条,写简单点就写成了2*N;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值