在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。 |
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
|
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。 |
Sample Input
1
8
5
0
|
Sample Output
1
92
10
|
Author
cgf
|
Source
2008 HZNU Programming Contest
|
#include<iostream>
using namespace std;
bool rows[10];
bool cols[10];
bool dig[40];
int N=0;
int LeftOrRight(int i,int j)
{
if(N-1-i-j>0)
{
return -1;
}
else if(N-1-i-j==0)
{
return N-1;
}
else return -2;
}
int UpOrDown(int i,int j)
{
if(i-j<0)
{
return -3;
}
else if(i-j==0)
{
return 3*N-4;
}
else
return -4;
}
bool setVisit(int i,int j,int &m1,int &m2)
{
bool isright=true;
int k1=LeftOrRight(i,j);
int k2=UpOrDown(i,j);
if(k1>0)
{
if(dig[k1])
{
isright=false;
}
else
m1=k1;
}
else{
if(!((i==0&&j==0)||(i==N-1&&j==N-1)))
{
if(dig[i+j])
{
isright=false;
}
else
{
m1=i+j;
}
}
else
m1=-1;
}
if(k2>0)
{
if(dig[k2])
{
isright=false;
}
else
m2=k2;
}
else{
if(!((i==0&&j==N-1)||(i==N-1&&j==0)))
{
if(dig[i-j+3*N-4])
{
isright=false;
}
else
{
m2=i-j+3*N-4;
}
}
else
m2=-1;
}
/*if(isright)
{
dig[m1]=true;
dig[m2]=true;
}*/
return isright;
}
int count1=0;
void Tial(int i,int n)
{
if(i>n-1)
{
count1++;
}
else{
for(int j=0;j<N;j++)
{
int m1=-1;
int m2=-1;
if(!rows[i]&&!cols[j]&&setVisit(i,j,m1,m2))
{
rows[i]=true;
cols[j]=true;
if(m1!=-1)
dig[m1]=true;
if(m2!=-1)
dig[m2]=true;
Tial(i+1,n);
rows[i]=false;
cols[j]=false;
if(m1!=-1)
dig[m1]=false;
if(m2!=-1)
dig[m2]=false;
}
}
}
}
int list[10];
void setList()
{
for(int i=1;i<=10;i++)
{
memset(rows,false,sizeof(rows));
memset(cols,false,sizeof(cols));
memset(dig,false,sizeof(dig));
count1=0;
N=i;
Tial(0,i);
list[i]=count1;
}
}
int main()
{
setList();
int m;
while(scanf("%d",&m))
{
if(m==0)
break;
cout<<list[m]<<endl;
}
return 0;
}