问题描述
n-皇后问题是在 n 行 n 列的棋盘上放置 n 个皇后,使得皇后彼此之间不受攻击,其规则是任意两个皇后不在同一行、同一列和相同的对角线上 (也就算国际象棋的皇后移动范围)
问题分析
拟采用以下思路解决 n-皇后问题:
第 i 个皇后放在第 i 行
从第一个皇后开始,对每个皇后,从其对应行 (第 i 个皇后对应第 i 行) 的第一列开始尝试 若可以放置,确定位置,考虑下一个皇后 若与之前的皇后冲突,则考虑下一列 若超出最后一列,则重新确定上一个皇后的位置
重复该过程,直到找到所有的放置方案
C 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <math.h>
#define N 4 //皇后个数
// 判断第 k 个皇后目前放置位置是否与前面的皇后冲突
int isplace(int pos[], int k){
int i;
for(i=1; i<k; i++){
if(pos[i]==pos[k] || fabs(i-k) == fabs(pos[i]-pos[k]))
return 0;
}
return 1;
}
int main(){
int i,j;
int count = 1;
int pos[N+1];
//初始化位置
for(i=1;i<=N;i++)
pos[i]=0;
j = 1;
while(j>=1){
pos[j]=pos[j]+1;
//尝试摆放第 i 个皇后
while(pos[j]<=N && !isplace(pos,j)){
pos[j]=pos[j]+1;
//得到一个摆放方案
}
if(pos[j]<=N && j==N){
printf("方案 %d:", count++);
for(i=1;i<=N;i++)
printf("%d", pos[i]);
printf("\n");
}
//考虑下一个皇后
if(pos[j]<=N && j<N){
j+=1;
}else{ //返回考虑上一个皇后
pos[j]=0;
j-=1;
}
}
return 1;
}