八皇后问题(回溯法)C语言求解

17 篇文章 0 订阅
17 篇文章 0 订阅

方法一:

//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;
}

有时间我会补充一下注释,大家可以先自己理解理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值