继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

搜索&回溯——N皇后(hdu2553)

九日王朝
关注TA
已关注
手记 180
粉丝 41
获赞 185

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2553

题目描述:

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


解决思路:

回溯官方课题~用这道题理解回溯再合适不过了,下面的代码也是初学回溯时所写的,感觉自己萌萌哒~


百科一下回溯法:

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:
1、定义一个解空间,它包含问题的解。
2、利用适于搜索的方法组织解空间。
3、利用深度优先法搜索解空间。
4、利用限界函数避免移动到不可能产生解的子空间。
问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。


其实说白了 就是 递归前改变一个状态,递归后再改回来~2333333   比如说

n++;

f(n)              //试探下一步

n--;

N皇后即,当前点可以放置皇后就试探性的放,当其所有子节点遍历完之后再接着考虑后面的选择

shu[i]=you[m+i]=zuo[m-i+n]=1;  //假设采取当前方案。 
hs(m+1);                       //走到下一行。 
shu[i]=you[m+i]=zuo[m-i+n]=0;  //执行完回溯还原。 


完整代码:


#include<stdio.h>#include<string.h> int shu[110],zuo[110],you[110];      //记录"上""左""右"状态。 int n,sum;int x[11]={0,1,0,0,2,10,4,40,92,352,724};//N=1~10答案,测试数据。 void hs(int m)//无剪枝完全回溯,对于每个可选择路线都会走一遍,然后还原。{	int i;	if(n<m)     //如果n<m了,即最后一行也走完了,sum++并返回。 	{	sum++;	return;}	for(i=1;i<=n;i++)   //回溯开始 	{		if(!shu[i]&&!you[m+i]&&!zuo[m-i+n]) //如果满足三个条件为0(可选) //注意zuo,you数组要是测试数据的2倍,左边减到负值时要加个n即从最右开始。 		{			shu[i]=you[m+i]=zuo[m-i+n]=1;  //假设采取当前方案。 			hs(m+1);                       //走到下一行。 			shu[i]=you[m+i]=zuo[m-i+n]=0;  //执行完回溯还原。 		}	}}int a[11];int main(){int nn;for(n=1;n<=10;n++)          //打表 {memset(shu,0,sizeof(n));    //三个记录状态的数组清零 memset(zuo,0,sizeof(n));memset(you,0,sizeof(n));     	sum=0;     	hs(1);                   //从第一行开始 	a[n]=sum;                //结果存在a数组里 }				while(~scanf("%d",&nn)&&nn){printf("%d\n",a[nn]);}}


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP