您的位置:首页 > 其它

HDU 2553 N皇后问题

2015-08-09 20:38 267 查看

N皇后问题

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

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

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

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

[align=left]Sample Input[/align]

1
8
5
0


[align=left]Sample Output[/align]

1
92
10
思路:我们没必要针对每个点的行和列进行判断,弄一个数组,即可判断行和列了,对斜线的判断也很简单,


附上详细解释:

#include <iostream>

#include <cstring>

#include <cstdio>

#include <algorithm>

#include <cmath>

#include <cstdlib>

using namespace std;

#define maxn 20

int n;

int a[maxn],f[maxn],sum;

bool check(int t)

{

for(int i=1;i<t;i++)//此循环用来判断列或斜线

{

if(f[i]==f[t]//判断是否在同一列|| t-i==abs(f[i]-f[t])//判断是否在同一斜线)//因为前面那个for循环我们已经判断了行,现在只用判断列和斜线方向就好了

{

return 0;

}

}

return 1;

}

void dfs(int t)

{

if(t>n)

{

sum++;//如果完成一次遍历,就加一,记录不同的种数

}else{

for(int i=1;i<=n;i++)

{

f[t]=i;//第二次搜索时,让其从1开始,因为前一次搜索,我们已经对其进行赋值,所以for循环的前t-1次循环都是用来让第t个皇后的行向下移动;

if(check(t))//对第t列进行查找

{

dfs(t+1);

}

}

}

}

int main()

{

int i;

memset(a,0,sizeof(a));//其实这两行用不用都无所谓

memset(f,0,sizeof(f));//

for(i=1;i<=10;i++)

{

sum=0,n=i;

dfs(1);//每一次从1开始,搜到i,看看有多少种

a[i]=sum;//把找到的值全部赋给a[i]

}

while(cin>>n)

{

if(n==0) break;

cout<<a
<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: