题目:
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10
解题思路:
DFS逐层考虑就行了,但是这道题做的时候一直超时,,,,后来才知道可以通过预处理节省时间,,,,预处理尤其对于一些输入范围比较小的题目有效,可以在输入之前把所有可能的情况考虑到并计算出结果,输入时直接调之前的结果就行了,这种技巧在复杂题目中也可以用,如果时间要求比较高,老是超时的话,可以考虑将某一部分重复计算的内容提前算好存储在数组中,直接调用就行了。
代码:
#include <iostream>
#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>using namespace std;
int n;
int ans=0;
int ma[11];int ab(int a){
if(a<0)return -a;
else return a;
}bool check(int x,int y){
bool an=true;
for(int i=1;i<=n;i++){
if(ma[i]==0)break;
if(i==x||ma[i]==y||ab(i-x)==ab(ma[i]-y)){
an=false;
break;
}
}
return an;
}
void dfs(int x){
if(x>n)ans++;
else{
for(int i=1;i<=n;i++){
ma[x]=0;
if(check(x,i)){
ma[x]=i;
dfs(x+1);
}
}
}
}int main(){
int a;
ma[1]=0;
int an[11];
for(int i=1;i<=10;i++){
n=i;
dfs(1);
an[i]=ans;
ans=0;
}
while((a=scanf("%d",&n))){
if(n==0)break;
printf("%d\n",an[n]);
}
cout<<"error,a="<<a<<endl;
system("pause");
return 0;
}