题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2553
题目:
Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
解题思路:
八皇后的扩展,其实和八皇后也没什么本质的区别。因为要保证一排一列以及对角线上唯一,我们可以从上到下一排一排遍历,每排保证一个皇后,这样将约束条件降到三个。
三个约束条件,一列很好保证,只需要一个数组v[i],记录第i列是否被放置即可。而两个斜对角线,其实我们也可以用同样的方法记录。对于从左上到右下的对角线,我们发现在对角线上的点(xi,yi)都有一个规律,xi-yi的值相等。同样对于右上到坐下的对角线上的点,xi+yi的值相等。所以我们可以用两个数组r[xi-yi+n],l[xi+yi]来分别记录他们。需要注意,xi-yi的值可能为负数,所以我们再数组上加一个偏移量n来保证其非负。
#include <iostream>
#include<bits/stdc++.h>
#define N 110
using namespace std;
int v[N],ans,l[N],r[N],d[N];
void dfs(int t,int n)
{
if(t==n+1)
{
ans++;
return ;
}
for(int i=1;i<=n;i++)
{
if(!v[i]&&!r[t-i+n]&&!l[t+i])
{
v[i]=r[t-i+n]=l[t+i]=1;
dfs(t+1,n);
v[i]=r[t-i+n]=l[t+i]=0;
}
}
}
int main()
{
for(int i=1;i<=10;i++)
{
ans=0;
dfs(1,i);
d[i]=ans;
}
int n;
while(~scanf("%d",&n)&&n)
{
cout<<d[n]<<endl;
}
}