N皇后问题 HDU--2553 思路清晰 与众不同

题目链接
这是一道深度搜索题,题目如下:

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。

你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

Output

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

Sample Input1

8
5
0

Sample Output1

92
10

这个题的大致题意是将n个棋子放在n×n的棋盘上,使n个棋子不同行不同列并且不同对角线共有多少种情况。
为了满足题意n个棋子必须在不同行,我们先将确定第一个棋子的位置,然后再从第二个棋子开始搜索,这个题我们需要标记列是否被占和左对角线是否被占和右对角线是否被占,所有的点都可以用坐标(x,y),来确定,而在同一个左对角线的点他们的x+y相同,在同一个右对角线的点他们的x-y相同,因此我们可以发现利用这个规律,对他们进行标记,写一个函数去判断这个点能不能放棋子,如果这个列/左对角线/右对角线已经访问过了则不能放在这。
这个题要注意在输入之前将1-10的结果提前存储好,也就是打表,这样才不会超时。
这里通过x+y-1将左对角线的序号分别标为1——2n-1,通过x-y+n将右对角线的序号分别标为1——2n-1,有兴趣的可以动笔在纸上试一下,这样更方便它们作为下标。
代码如下:
#include<iostream>
using namespace std;
int icount;
int n;
int bookh[11];
int zxie[25];
int yxie[25];
int judge(int x,int y)
{
 	if(bookh[y]==0&&zxie[x+y-1]==0&&yxie[x-y+n]==0)
 	return 1;
 	else
 	return 0;
}
void dfs(int line)
{
 	if(line==n+1)//搜索到n+1行时就说明棋盘确定了,情况加一 
 	{
  		icount++;
  		return;
 	}
 	for(int i=1;i<=n;i++)//确定此行的棋子在第i列 
 	{
  		if(judge(line,i))
  		{
   			bookh[i]=1;
   			zxie[line+i-1]=1;
   			yxie[line-i+n]=1;
   			dfs(line+1);
   			bookh[i]=0;
   			zxie[line+i-1]=0;
   			yxie[line-i+n]=0;
  		} 
 	}
}
int main()
{
 	int end[11];
 	for(n=1;n<=10;n++)
 	{
  		icount=0;
  		for(int i=1;i<=n;i++)//确定第一行的在第i列 
  		{
   			bookh[i]=1;//标记列被占 
   			zxie[i]=1;//标记左斜对角线被占 
   			yxie[1-i+n]=1;//标记右边斜对角线被占 
   			dfs(2);//第一行已经确定了,要从第二行搜索 
   			bookh[i]=0;
   			zxie[i]=0;
   			yxie[1-i+n]=0;
  		}
  		end[n]=icount;//打表 
 	}
 	while(cin>>n&&n!=0)
 	{ 
  		cout<<end[n]<<endl;
 	}
 	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值