8皇后问题用全排列方法解决----《剑指offer》

题目

在这里插入图片描述
例如,其中一种解:

1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0

思路

  我们可以将棋盘用一个二维数组表示,棋盘上用0代表不同的位置,1表示皇后所在的位置。
由于每一行只能有一个皇后,并且皇后不能处于同一列,所以,每一行皇后位置的下标必然不同且唯一。
  例如,我们可以将上图皇后在每一行的位置记录为: 0 4 7 5 2 6 1 3
  如果按照下标从0开始记数,那图中的结果可以表示为:1 5 8 6 3 7 2 4
  通过观察发现,原来8皇后问题可以看成将数字1-8全排列的问题,但是全排列的结果要满足一定要求。
  
  
  那这么要求是什么呢? 那就是所有的皇后不能在同一条斜线上(反斜线也不行)。我们以第图中的第5行为例。如果第5行的位置在坐标3上,
  那么第1行不能在 3+(5-1) = 7
  那么第2行不能在 3+(5-2) = 6
  那么第3行不能在 3+(5-3) = 5 且 3-(5-3) = 1
  那么第4行不能在 3+(5-4) = 4 且 3-(5-4) = 2
  那么第6行不能在 3+(6-5) = 2 且 3-(6-5) = 2
  那么第7行不能在 3+(7-5) = 5 且 3-(7-5) = 1
  那么第8行不能在 3+(8-5) = 6
不难发现:每行的下标之间的距离,不能等于每行之间的距离。这里的距离可以用两数相减的绝对值来计算。

代码

#include <iostream>
#include <math.h>
using  namespace std;


//  判断条件
//  下标0-7分别对应正方体编号1-8的顶点
bool checking(int data[8])
{
    bool ok = true;
    for (int i = 0; i < 8; ++i)
    {
        for (int j = i + 1; j < 8; ++j)
        {
            if (abs(data[j]-data[i]) == j - i)
            {
                ok = false;
                return ok;
            }
        }
    }
    return ok;
}


//  全排列
void Permutation(int data[],int position = 0, int len = 8)
{
    if (position == len - 1 && checking(data))
    {
        for (int i = 0; i < len; ++i)
        {
          cout << data[i] << ' ';
        }
        cout << endl;

        //  找到一种解,就退出了
        //  exit(EXIT_SUCCESS);
        return;
    }

    for (int i = position; i < len; ++i)
    {
        std::swap(data[position], data[i]);
        Permutation(data, position + 1);
        std::swap(data[position], data[i]);
    }
}

int main()
{
    int data[8] = {1,2,3,4,5,6,7,8};
    Permutation(data);

    return EXIT_SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值