在n*n的棋盘上放置彼此不受攻击的n个皇后,按照国际象棋的规则,
皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
暴力算法
#include<stdio.h>
#include<math.h>
int count=0;
bool ok(int *a,int n){//绝对没有在同一行的,因为赋值时已经确定了
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]==a[j])//列比较是否有同列的
return false;
if(abs(i-j)==abs(a[i]-a[j]))
return false;
}
}
return true;
}
int main(){
int n;
printf("请输入有几个皇后:");
scanf("%d",&n);
int *a;
a=new int[n];
int num;
for(int i=0;i<pow(n,n);i++){
num=i;
for(int j=0;j<n;j++){
a[j]=num%n;//每一行的皇后放在哪一列,j代表第几行,num代表放到哪一列上,即a[j]代表的是列
num/=n;
}
if(ok(a,n))
count++;
}
printf("%d个皇后共有%d种方案\n",n,count);
return 0;
}
回溯法
#include<stdio.h>
#include<math.h>
int count=0;
int n;
int *a;
bool ok(int t){//绝对没有在同一行的,因为赋值时已经确定了
for(int i=0;i<=t;i++){
for(int j=i+1;j<=t;j++){
if(a[i]==a[j])//列比较是否有同列的
return false;
if(abs(i-j)==abs(a[i]-a[j]))
return false;
}
}
return true;
}
void trace(int t){
if(t==n){
count++;
return;
}
for(int i=0;i<n;i++){
a[t]=i;
if(ok(t))
trace(t+1);
a[t]=0;
}
}
int main(){
printf("请输入有几个皇后:");
scanf("%d",&n);
a=new int[n];
trace(0);
printf("%d个皇后共有%d种方案\n",n,count);
return 0;
}