方法一:
//N_Queen
#include<iostream>
using namespace std;
#define N 100 //定义最多求解100皇后问题
int x[N]; //存放N皇后问题的解
//判断皇后K放在x[k]列是否冲突
int Place(int k) {
for(int i = 0; i < k; i++) {
if(x[i] == x[k] || abs(i - k) == abs(x[i] - x[k])) //违反约束条件
return 1; //冲突,返回1
}
return 0; //不冲突,返回0
}
//打印N皇后问题的一个解
void PrintQueen(int n) {
for(int i = 0; i < n; i++) {
printf("%5d", x[i] + 1); //数组下标从0开始,打印要求序号从1开始
}
printf("\n");
}
//回溯法求解
void Queen(int n) {
int k = 0, num = 0; //num存储解的个数
while (k >= 0) //摆放皇后k,注意0<=k<n
{
x[k]++; //在下一列摆放皇后k
while (x[k] < n && Place(k) == 1 ) { //发生冲突
x[k]++; //皇后K试探下一列
}
if(x[k] < n && k == n - 1) { //得到一个解,输出
printf("第%d个解是:", ++num);
PrintQueen(n);
} else if (x[k] < n && k < n - 1) { //尚有皇后未摆放
k = k + 1; //准备摆放下一个皇后
} else {
x[k--] = -1; //重置x[k],回溯,重新摆放下一个皇后k
}
}
}
int main() {
int i , n;
printf("请输入皇后的个数:");
scanf("%d", &n);
for(int i = 0; i < n; i++) {
x[i] = -1;
}
Queen(n);
system("pause");
return 0;
}
方法二:
摘自百度百科https://baike.baidu.com/item/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98/11053477?fr=aladdin
#include <iostream>
using namespace std;
const int N = 8;
int arr[10], total_cnt;
// arr记录每一行(X)皇后的Y坐标
bool isPlaceOK(int *a, int n, int c) {
for (int i = 1; i <= n - 1; ++i) {
if (a[i] == c || a[i] - i == c - n || a[i] + i == c + n)
return false;
//检查位置是否可以放
//c是将要放置的位置
//a[i] == c如果放在同一列,false
//a[i] -+ i = c -+ n 如果在对角线上,false
}
return true;
}
void printSol(int *a) {
for (int i = 1; i <= N; ++i) { //遍历每一行
for (int j = 1; j <= N; ++j) { //遍历每一列
cout << (a[i] == j ? "X" : "-") << " ";;
} //如果标记数组中这一行的皇后放在j位置,则输出X,否则输出-,
//用空格分隔
cout << endl; //每一行输出一个换行
}
cout << endl; //每一组数据一个换行分隔
}
void addQueen(int *a, int n) {
if (n > N) { //n代表从第一行开始放置
printSol(a);
total_cnt++;
return ;
}
for (int i = 1; i <= N; ++i) { //i从第1列到第N列遍历
if (isPlaceOK(a, n, i)) {
a[n] = i; //如果可以放置,就把皇后放在第n行第i列
addQueen(a, n + 1);
}
}
}
int main() {
addQueen(arr, 1);
cout << "total: " << total_cnt << " solutions.\n";
return 0;
}
有时间我会补充一下注释,大家可以先自己理解理解