八皇后问题 递归解决 回溯算法简单应用

八皇后问题算是一个回溯算法的典型案例。虽然我不太懂回溯,但该问题很有内味(。・∀・)ノ゙,下面描述一下我的解法在这里插入图片描述
  八皇后问题指在一个8×8的棋盘上,摆放八个皇后,要求这八个皇后不能互相攻击,每个皇后的攻击范围为同一行、同一列、同一个斜线,也就是任意两个皇后不能处于同一行、同一列、同一斜线上,问题就是这八个皇后有多少种站法。(我懒得用主对角线、副对角线什么的解释了,大家都懂( ̄▽ ̄)")

显然每一行、每一列都有且仅有一个皇后,8×8的棋盘比作8阶矩阵

若两个元素位于同一主对角线,则他们行数差等于列数差;若两个元素位于同一副对角线,则他们行数差加列数差为0。OK,数学准备工作完成,具体参考代码注释吧

#include <iostream>
#include <stdio.h>
#include <algorithm>

using namespace std;

int chess[9][9], queen[9], sum = 0;//皇后数组下标为该皇后所站行数,值为所站列数

bool can_place(int row, int column) {
    
    //row行,column列能否放置皇后
    for(int i = 1; queen[i] != 0; i++) {
    
    //i为已站好皇后行数,queen[i]为他们所在列数
        if(column == queen[i] || row - i == column - queen[i] || row - i + column - queen[i] == 0) {
    
    
            return false;//同一列、同一主对角线、同一副对角线均不可
        }
    }
    return true;
}

void place_queen(int row) {
    
    //在第row行放置第row个皇后
    if(row == 9) {
    
     //八个皇后已放置完毕
        cout << "第" << ++sum << "种:" << endl;
        for(int a = 1; a < 9; a++) {
    
    
            for(int b = 1; b < 9; b++) {
    
    
                cout << chess[a][b] << " ";
            }
            cout << endl;
        }
        cout << endl;
        return;//该句可有可无,提高一丢丢效率吧
    }
    for(int column = 1; column <= 8; column++) {
    
    
        if(can_place(row, column)) {
    
    
            queen[row] = column;
            chess[row][column] = 1;//0表示该位置无皇后,1表示有皇后
            place_queen(row + 1);//每次调用该递归会确定一种八皇后的站法
            chess[row][column] = 0;//接上句,确定一种站法后需要归零
            queen[row] = 0;
        }
    }
    return;
}

int main() {
    
    
    place_queen(1);
    cout << sum << endl;
    return 0;
}

以前学习C的时候,毫无算法概念,用过暴力求解,还真就做出来了,但耗时感人。其实我现在仍然觉得暴力出奇迹

猜你喜欢

转载自blog.csdn.net/ccmtvv/article/details/105935745