N皇后问题

由于皇后的位置受到上述三条规则约束,我们必须通过一些技术手段来判断当前皇后的位置是否合法。

1.皇后的编号从 0 ~ N - 1 (N表示皇后的数量),这样编号的想法很简单:数组下标从0开始(这样方便后续对其位置的说明)。

2.使用一维数组 putInf 对每一行皇后的存放位置进行保存,因此得到解向量 (putInf[0], putInf[1], putInf[3], … , putInf[N - 1]),putInf[i] 表示第 i 个皇后被放置到了第 putInf[i] + 1 列上(putInf数组中存储的是列号,范围为 0 ~ N - 1);

3.第二个条件:各皇后不同列, N 皇后放在 N x N 的棋盘上,那么每一列最多且必须放置一个皇后,这里我用了一个 used数组 对每一列的摆放情况进行记录, used[i] = true 表示 第 i 列 已经放置了皇后,used[i] = false 表示第i列暂未放置皇后,这样我们可以保证不在一列上放置多个皇后,也就能满足 各皇后不同列 的规则。

4.各皇后不能处于同一对角线位置:假设两皇后位置坐标分别为(i, j) 、(l, k),那么根据直线斜率公式:

(i - l) / (j - k) = 1 求解得 i - l == j - k ①
(i - l) / (j - k) = -1 求解得 i - l == k - j ②
这两种情况出现时表明处于同一对角线,那么要满足摆放规则就必须满足
| i - l | != | j - k | (“| |” 表示绝对值)
完整代码

 
#include<stdio.h>
#include<malloc.h>
#include<math.h>
 
//判断把它放在这是是否是适用的 
 
int place(int *paraSolution,int paraT){
	int j;
	for(j = 0;j < paraT;j++){
		 if ((abs(paraT - j) == abs(paraSolution[j] - paraSolution[paraT])) || (paraSolution[j] == paraSolution[paraT]))
	return 0;
	}
	return 1;
}
 
//Backtracking.回溯。 
 
void backtracking(int* paraSolution,int paraN, int paraT){
	int i;
	if(paraT>paraN){
		for(i = 1;i <= paraN;i++)
		printf("%d",paraSolution[i]);
		printf("\r\n");
	}
	else
	{
		for(i = 1;i <= paraN;i++){
			paraSolution[paraT] = i;
			if(place(paraSolution,paraT))
			backtracking(paraSolution,paraN,paraT + 1);
		}
	}
}
 
//Title: n queens.<br>
 
void nQueen(int paraN){
	int i;
	int*solution = (int*)malloc((paraN + 1) * sizeof(int));
	for(i = 0;i <= paraN;i++)
	solution[i] = 0;
	
	backtracking(solution,paraN,1);
}
 
//The entrace.输出数据 
 
int main(){
	printf("输入个数: \r\n");
	int n;
	scanf("%d",&n);
	nQueen(n);//括号里面写具体有多少个元素 
	return 1;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值