N皇后问题(回溯算法解法)

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3464    Accepted Submission(s): 1599


Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

 

 

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量
 

 

Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
 

 

Sample Input
8
 

 

Sample Output
92

由于棋盘的每列只有一个皇后,所i可以用一维向量A(a1,a2,a3……an)来表示第i列皇后所在的行a[i],即解空间的每个结点都有n个儿子,因此解空间大小为n^n,这是一颗子集树。

约束条件是斜率和行号都不可以相等。

回溯算法解题思路:
1.针对给定的问题,定义问题的解空间(子集树还是排列树)
2.确定易于搜索的解空间结构
3.以深度优先的方法搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。


#include <cstdio>
#include <iostream> 
#include <cmath>
using namespace std;

#define NUM 20
int n;
int x[NUM]; 
int sum; 

inline bool Place(int t) 
{ 
	int i; 
	for (i=1; i<t; i++) 
		if ((abs(t-i) == abs(x[i]-x[t])) || (x[i] == x[t])) //斜率相等或者行号相等 
			return false; 
	return true; 
} 

void Backtrack(int t) 
{ 
	int i;
	if (t>n) 
	{
		sum++;
	}
	else
		for (i=1; i<=n; i++) 
		{
			x[t] = i;
			if (Place(t)) Backtrack(t+1);
		}
} 

int main() 
{ 
	while (cin>>n)
	{
		sum = 0;
		Backtrack(1);
		printf("%d\n", sum);
	}
	return 0; 
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值