题目描述
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
输入
测试数据由多组测试样例组成。每组测试数据第一行输入一个正整数 n ( 1 <= n <= 10 )
输出
输出有多少种合法的放置方法
样例输入 Copy
1
5
样例输出 Copy
1
10
思路:
这道题虽然步骤很多,但是有想法写就很顺,首先初始化一个二维数组,然后写一个检查函数,
检查N皇后的横纵4个45度角是否有棋子,如果没有就返回true,然后开始写dfs函数,
函数的出口即行数相等。但是这道题提交总是超时,改了几个小地方优化但是依然超时,
最后看了下题目要求1<=n<=10,然后就将10种情况都列了出来才AC。
AC代码:
#include <cstdio>
#include <iostream>
using namespace std;
int n,ans=0;
char s[15][15];
int dir[4][2]={{-1,1},{1,-1},{-1,-1},{1,1}};
int AC[10]={1,0,0,2,10,4,40,92,352,724};
void init(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
s[i][j]='.';
}
}
}
bool check(int x,int y){
for(int i=0;i<x;i++){
if(s[i][y]=='Q'){
return false;
}
}
for(int i=0;i<y;i++){
if(s[x][i]=='Q'){
return false;
}
}
for(int i=0;i<4;i++){
int tx=x;
int ty=y;
while(tx>=0&&ty>=0&&tx<n&&ty<n){
if(s[tx][ty]=='Q'){
return false;
}
tx+=dir[i][0];
ty+=dir[i][1];
}
}
return true;
}
void dfs(int cow){
if(cow==n){
ans++;
return;
}
for(int i=0;i<n;i++){
if(check(cow,i)){
s[cow][i]='Q';
dfs(cow+1);
s[cow][i]='.';
}
}
}
int main(){
while(cin>>n){
if(n<=10){
cout<<AC[n-1]<<endl;
}else{
ans=0;
init();
dfs(0);
cout<<ans<<endl;
}
}
return 0;
}