八皇后问题解法

首先我们看下什么是八皇后问题,看下官方回答。
{八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。}
通俗的讲就是在8*8的棋盘上放8个棋子,使得不能有2个及其以上的棋子在同一行、同一列或者是同一条对角线上
现在设计一个程序,输出全部的解法及其解的总数;

#include <stdio.h>
#include <stdbool.h> 
//全局变量数据初始化
int place[8] = { 0 };//第n个皇后所占位置的列号。
bool flag[8] = { 1,1,1,1,1,1,1,1 };//标志数组,表示第col列是否可站,1表示不冲突。
bool d1[15] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };  //表示上三角形是否可占
bool d2[15] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };   // 表示下三角形是否可占
int number = 0; //用于统计解的数量(八皇后一共92个解)。
void print();   //注意不是stdio.h里面的printf函数,是自定义的函数。
void gernerate(int n);   //其中n代表的是从第n+1行放置皇后。
int main()
{
	gernerate(0);  //这里的参数0代表从第1列放置皇后,有初始化的作用吧。
	return 0; //主函数就是这么简单,果然是神才用递归,码农用迭代.
}
void gernerate(int n)
{
	int col;
	for (col = 0; col < 8; col++)   //每个皇后有八种可能的列
	{
		if (flag[col] && d1[n - col + 7] && d2[n + col])   //判读位置是否冲突,注意这其中的条件是每个都要满足。
		{
			place[n] = col;   // 在n行col列摆放皇后
			flag[col] = false;   //宣布占领第col列
			d1[n - col + 7] = false;  //占领两个对角线
			d2[n + col] = false;
			if (n < 7)  //八个皇后没有摆完,递归摆放下一行里面的皇后
				gernerate(n + 1);
			else
				print();   //n==7,皇后都摆完了,打印结果。
			//回溯,考虑其他可行方案
			flag[col] = true;
			d1[n - col + 7] = true;
			d2[n + col] = true;

		}
	}
}

void  print()// 打印结果,第n个皇后所占位置的列号。
{
	int col, i, j;
	number++;
	printf("No.%d\n", number); 
	//printf("八皇后的结果是:");
	/*
	for(col=0;col<8;col++)
	printf("%d行%d列",col,place[col]);
	printf("\n");
	*/
	int table[8][8] = { 0 };
	for (col = 0; col < 8; col++)
		table[col][place[col]] = 1;
	for (i=0;i<8;i++)
	{
		for (j = 0; j < 8; j++)
		{
			printf("%d", table[i][j]);
		}
		printf("\n");
	}
}

运行图
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值