一、N皇后问题的概念
n 皇后问题,研究的是如何将 n 个皇后放置在 n×n 的棋盘上,如果一个皇后出现在另一个皇后的同一行,同一列或者斜对角,那么则失败。可以通过列举出在棋盘上所有的情况,然后判断每个组合是不是符合的条件。
二、非递归解法:
#include<stdio.h>
#include<math.h>
#define N 4
int q[N + 1]; //存储皇后的列号 q[i]表示第i个皇后,处于第i行上的q[i]列
int check(int j){ //检查第j个皇后的位置是否合法
int i;
for(i = 1;i < j;i++){
if(q[i] == q[j] || abs(i - j) == abs(q[i] - q[j])){ //判断是否在同列或者同斜线
return 0;
}
}
return 1;
}
void queen(){ //求解N皇后的方案
int i;
for(i = 1;i <= N;i++){
q[i] = 0;
}
int answer = 0; //方案数
int j = 1; //表示正在摆放第j个皇后
while(j >= 1){
q[j] = q[j] + 1; //让第j个皇后的位置向后移1摆放
while(q[j] <= N && !check(j)){ //判断位置是否合法
q[j] = q[j] + 1; //不合法则往后移1位
}
if(q[j] <= N){ //表示第j个皇后的位置摆放是合法的
if(j == N){ //已经摆放了N个皇后,找到了N皇后的一组解
answer += 1;
printf("方案%d: ",answer);
for(i = 1;i <= N;i++){
printf("%d ",q[i]);
}
printf("\n");
}else{ //还没摆放完N个皇后,继续摆放下一个皇后
j = j + 1;
}
}else{ //表示第j个皇后找不到一个合法的摆放位置
q[j] = 0; //还原第j个皇后的位置
j = j - 1; //回溯
}
}
}
int main(){
queen();
return 0;
}
三、递归解法
#include<stdio.h>
#include<math.h>
#define N 4
int answer = 0; //方案数
int q[N + 1]; //存储皇后的列号 q[i]表示第i个皇后,处于第i行上的q[i]列
int check(int j){ //检查第j个皇后的位置是否合法
int i;
for(i = 1;i < j;i++){
if(q[i] == q[j] || abs(i - j) == abs(q[i] - q[j])){ //判断是否在同列或者同斜线
return 0;
}
}
return 1;
}
void queen(int j){ //求解N皇后的方案
int i;
for(i = 1; i <= N; i++){
q[j] = i;
if(check(j)){ //当摆放位置合法时
if(j == N){ //找到了N皇后的一组解
answer += 1;
printf("方案%d: ",answer);
for(i = 1; i <= N; i++){
printf("%d ",q[i]);
}
printf("\n");
} else{
queen(j + 1); //递归摆放下一个皇后的位置
}
}
}
}
int main(){
queen(1);
return 0;
}
运行结果: