题意:在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
思路:X(j)表示一个解的空间,j表示行数,里面的值表示可以放置在的列数,抽象约束条件得到能放置一个皇后的约束条件(1)X(i)!=X(k);(2)abs(X(i)-X(k))!=abs(i-k)。应用回溯法,当可以放置皇后时就继续到下一行,不行的话就返回到第一行,重新检验要放的列数,如此反复,直到将所有解解出。
感想:书上的例题。不多说我看懂了。
代码:
#include<iostream>
#include<cmath>
using namespace std;
int x[11],N,sum;
bool place(int k){ //判断第K个皇后是否可以加入
for(int i=1;i<k;i++){
if(x[i]==x[k] || abs(k-i)==abs(x[k]-x[i]))
return false;
}
return true ;
}
void backtrack(int k){ //k的初值为1
if(k>N) //安排完N个皇后后sum++
sum++;
else{
for(int i=1;i<=N;i++){ //找第K个皇后的列坐标
x[k]=i;
if(place(k)){
backtrack(k+1);
}
}
}
}
int main(){
int ans[11];
for(N=1;N<=10;N++){
sum=0;
backtrack(1);
ans[N]=sum;
}
while(scanf("%d",&N)!=EOF && N){
printf("%d\n",ans[N]);
}
return 0;
}
#include<cmath>
using namespace std;
int x[11],N,sum;
bool place(int k){ //判断第K个皇后是否可以加入
for(int i=1;i<k;i++){
if(x[i]==x[k] || abs(k-i)==abs(x[k]-x[i]))
return false;
}
return true ;
}
void backtrack(int k){ //k的初值为1
if(k>N) //安排完N个皇后后sum++
sum++;
else{
for(int i=1;i<=N;i++){ //找第K个皇后的列坐标
x[k]=i;
if(place(k)){
backtrack(k+1);
}
}
}
}
int main(){
int ans[11];
for(N=1;N<=10;N++){
sum=0;
backtrack(1);
ans[N]=sum;
}
while(scanf("%d",&N)!=EOF && N){
printf("%d\n",ans[N]);
}
return 0;
}