回溯法之n皇后问题

要在n*n的国际象棋棋盘上,在不同的每行每列都放置有一个皇后,而皇后之间不可以在同一行同一列和同一对角线上,给定n,问有多少种放皇后的方法。

分析:利用深度搜索Dfs进行穷举式的搜索,在搜索过程中剔除无用的解。

思路:设定对每行的每个棋格进行逐个遍历,如果这个棋子放置符合规则就进行深一步的放置,即跳到下一行去找符合放置的棋子,周而复始,直到行的值等于n。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int n,cnt=0;
bool place(int k/*当前行数*/,int x[])
{
	for(int j=1;j<k;j++)//Judging the site whether places or not
 	{
  		if((x[k]==x[j]||abs(k-j)==abs(x[k]-x[j])))
   			return false;
 	}
 	return true;
}
void dfs(int t,int x[])//backtrack
{
 	if(t==n+1)//t>n
  		cnt++;
 	else
 	{
  		for(int i=1;i<=n;i++)//the essential part
		{
   			x[t] = i;
   			if(place(t,x))
    				dfs(t+1,x);
  		}
 	}
 }
 int main()
{
	 int x[n+1];//存储列号
	 cin>>n;
	 memset(x,0,sizeof(x));
	 dfs(1,x);
	 cout<<cnt<<endl; 
	 
} 

其实没有必要去过深入的知道回溯的过程,因为实在在复杂,只要自然语义的理解就可以了。反正它的过程就是一颗树,先搜出一个解,然后回到父节点,去搜下面的子节点,当都搜过了,父节点就没有节点可搜了,继续回到它的父节点往下搜索,而这个过程就是在递归中实现的,递归第一次直接到后面,然后从何往前,只要递归语句在一个for循环里,就可以达到回溯的效果。
ps:研究这个问题真是太爽了,星期六想了一天,晚上上算法课又刚好讲了回溯法,如鱼得水。不过还是要感谢我身边还有一些优秀的同学让我每天激情澎湃的搞编程啦,昨天才上手的C++,因为要搞STL了。。。感觉用起来比C爽了不少…嘻嘻,欲知后事如何,请看下回分解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值