(P81)stl(九):用STL算法解决八皇后问题

1.八皇后问题

  • 八皇后问题是一个以国际象棋为背景的问题:如何能够在8*8的国际象棋的棋盘上放置8个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任意两个皇后都不能处于同一条横行、纵行或者斜线上。
    在这里插入图片描述

2.回溯递归法(传统方法)

  • (1)从第一列开始,为皇后找到安全位置|y1-y2|!=|x1-x2|,然后跳到下一列
    不能是同一行,同一列,同一个斜线
  • (2)如果在第n列出现死胡同,如果该列为第一列,棋局失败,否则后退到上一列,在进行回溯
  • (3)如果在第8列找到了安全位置,则棋局成功。
  • 回溯是C语言的方法
    在这里插入图片描述

3.C++算法:next_permutation

  • next_permutation,得到下一个排列
    全排列

  • 8个数字可以表示棋盘上的坐标,两两比较这些坐标是否是互斥的,如果都是互斥的,说明他是其中的一个解。
    皇后的坐标表示(y,x),y表示序号,x表示值,eg:(7,5)表示下标为7,值是5
    图中的任意2个坐标不可能在同一行,也不可能在同一列,因为这是由上面表示的方式决定的
    如何判定2个坐标在同一个斜线上面呢?
    可以用|y1-y2| = |x1-x2|,斜率是45°,说明是在同一条斜线上面。
    两两比较,(0,0)和(1,1),(2,2)比较以此类推。如果都不在同一条斜线上面,说明这一组坐标是一个解。
    再生成下一个排列继续求解。
    在这里插入图片描述

  • 这是由循环来解决的。

  • eg:P81\01.cpp

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
void print_element(int n)
{
    cout <<n<<' ';
}

int main(void)
{
    int a[] = {1,2,3,4};
    vector<int> v(a,a+4);
    for_each(v.begin(), v.end(), print_element);
    cout <<endl;

    //编序型算法
    while (next_permutation(v.begin(), v.end()))
    {
        for_each(v.begin(), v.end(), print_element);
        cout<<endl;

    }
    
}


  • 测试:1,2,3,4输出有24种排列
    在这里插入图片描述

  • eg:P81\02.cpp

#include <cmath>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
const int MAX = 8;

//表示棋盘向量,8个元素的值都是为0
vector<int> board(MAX);

void show_result()
{
    //i表示y,board[i]表示x
    for(size_t i = 0; i < board.size(); i++)
    {
        cout<< "(" << i << "," << board[i] << ")";
    }
    cout << endl;
}

//使用循环来解
int check_cross() 
{
    //这种坐标表示方法,表示他们既不在同一行也不在同一列
    //这里的j和i都代表y坐标,就是行
    for (size_t i = 0; i < board.size(); i++)
    {
        for (size_t j = i + 1; j < board.size(); j++)
        {
            //y坐标相减是否等于x坐标相减
            if ((j-i) == (size_t)abs(board[j] - board[i]))
                return 1;
        }
    }

    return 0;
}

void put_chess()
{
    while(next_permutation(board.begin(), board.end()))
    {
        //这个排列所代表的坐标是否有界
        //判断是否是一个解
        if(!check_cross())
        {
            show_result();//若是解,则打印坐标
        }
    }
}

int main()
{
    //初始化为0-7
    for(size_t i = 0; i < board.size(); i++)
    {
        board[i] = i;
    }

    //将棋子放到棋盘上面,即生成下一个排列
    put_chess();
    return 0;
}
  • 测试:
    8皇后问题总共有92个解
    在这里插入图片描述
    把第一个解画一下
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢打篮球的普通人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值