八皇后问题C++

来源:互联网 发布:银行模拟教学软件 编辑:程序博客网 时间:2024/06/06 01:39

八皇后是一道很具典型性的题目。它的基本要求是这样的:在一个8*8的矩阵上面放置8个物体,

一个矩阵点只允许放置一个物体,任意两个点不能在一行上,也不能在一列上,不能在一条左

斜线上,当然也不能在一条右斜线上。

    初看到这道题目,大家的第一印象是遍历,

但是经过实践之后发现遍历其实不好写,而且复杂度很低。

不仅需要遍历8*8*8*8*8*8*8*8*8 = 2^24次数据,还要判断各种条件,

实际的计算复杂度还要比较这个高。其实我们仔细看一看,这中间很多的计算其实很多是不需要的,

因为如果我们在某一行没有可以插入的数据的话,那么这后面的行其实就不用考虑了。

也就是说,我们只有在保证前面 插入的物体都合法有效的情况下,

才能进行下一次的物体插入。无谓的遍历只会是无用功。

   那么,我们应该怎么做呢?其实步骤不太难:

    (1)在第n行寻找可以插入的位置,中间涉及到位置合法性的判断

    (2)如果没有可以插入的位置,返回

    (3)如果有可以插入的位置, 插入数据。此时再判断是否已经是最后一行,如果是,打印输出返回;反之继续对下一行数据进行试探处理。


代码:


#include <iostream>
#include <cstdio>
using namespace std;
static int gEightQueen[8] = { 0 }, gCount = 0;
void print()//输出每一种情况下棋盘中皇后的摆放情况
{
    for (int outer = 0; outer < 8; outer++)
    {
        for (int inner = 0; inner < gEightQueen[outer]; inner++)
            cout << " ";
        for (int inner = gEightQueen[outer] + 1; inner < 8; inner++)
            cout << "";
        cout <<"#" << endl;
    }
    cout << "========\n";
}
int check_pos_valid(int loop, int value)//检查是否存在有多个皇后在同一行/列/对角线的情况
{
    int index;
    int data;
    for (index = 0; index < loop; index++)
    {
        data = gEightQueen[index];
        if (value == data)
            return 0;
        if ((index + data) == (loop + value))
            return 0;
        if ((index - data) == (loop - value))
            return 0;
    }
    return 1;
}
void eight_queen(int index)
{
    int loop;
    for (loop = 0; loop < 8; loop++)
    {
        if (check_pos_valid(index, loop))
        {
            gEightQueen[index] = loop;
            if (7 == index)
            {
                gCount++, print();
                gEightQueen[index] = 0;
                return;
            }
            eight_queen(index + 1);
            gEightQueen[index] = 0;
        }
    }
}
int main(int argc, char*argv[])
{
    eight_queen(0);
    cout << "total=" << gCount << endl;
    return 0;
}


0 0
原创粉丝点击