在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。Output共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。Sample Input
1 8 5 0
Sample Output
1 92 10
很水的一道搜索题。。
#include<iostream> #include<queue> #include<cstring> using namespace std; int col[15]; int n,ans; void dfs(int cur) { if(cur==n)//递归边界 ans++; else { for(int i=0;i<n;i++) { bool ok=true; col[cur]=i;//尝试把第cur行的皇后放在第i列 for(int j=0;j<cur;j++)//只用判断是否和前面的皇后冲突 { if(col[cur]==col[j]||cur-col[cur]==j-col[j]||cur+col[cur]==j+col[j]) { ok=false; break; } } if(ok) dfs(cur+1);//如果满足条件,继续搜索下一行的皇后摆放位置 } } } int main() { while(cin>>n,n) { ans=0; dfs(0); cout<<ans<<endl; } return 0; }
然而会超时。。HD的数据是很多重复的数据,结果就超时了。因为数据只有10组,所以可以打表。
#include<iostream> int a[12] = {0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724}; int main() { int n; while(cin>>n,n) cout<<s[n]<<endl; return 0; }
我们还可以对程序的效率进行优化。
#include<iostream> #include<queue> #include<cstring> using namespace std; bool vis[3][20]; int n,ans; void dfs(int cur) { if(cur==n) ans++; else for(int i=0;i<n;i++) { if(!vis[0][i]&&!vis[1][cur-i+n]&&!vis[2][cur+i])//用二维数组分别判断当前皇后所在的列和主副对角线上是否有其他皇后 { vis[0][i]=vis[1][cur-i+n]=vis[2][cur+i]=true; dfs(cur+1); vis[0][i]=vis[1][cur-i+n]=vis[2][cur+i]=false;//关键,回溯。 } } } int main() { while(cin>>n,n) { memset(vis,false,sizeof(vis)); ans=0; dfs(0); cout<<ans<<endl; } return 0; }