当前位置: 首页 > wzjs >正文

北京高端建设网站网络营销案例视频

北京高端建设网站,网络营销案例视频,做政协网站软件的公司,wordpress最新版优化问题描述 在一个 的国际象棋棋盘上放置 个皇后,使得任意两个皇后都不能处于同一行、同一列或同一斜线上。目标是找出所有满足该条件的皇后放置方案。 时间复杂度是O(n!),对于n 乘 n的格子,每行都有n种选择,选择可能依次递减。同时要便随着…

问题描述

在一个  的国际象棋棋盘上放置  个皇后,使得任意两个皇后都不能处于同一行、同一列或同一斜线上。目标是找出所有满足该条件的皇后放置方案。

时间复杂度是O(n!),对于n 乘 n的格子,每行都有n种选择,选择可能依次递减。同时要便随着大量剪枝。

一,经典解法

调用递归,使用类的成员变量或全局变量,引用传参等方法收集可能。

里面关于如何判断两个皇后是否在同一条斜线上,利用共斜线的话是斜率等于1或-1,利用斜率,即两个的坐标:行的变化量等于列的变化量。

要有封装和简化的思想。将原来代码量大的函数抽离一部分封装成函数,既使代码简洁,又方便后面修改。

思路

依次检验每个坐标符不符合条件,如果符合就收集进temp临时向量中,知道遇到终止条件后将temp添加进ans里,return返回。

代码

class NQueen
{
public:NQueen(int N);void printAns();~NQueen() = default;
private:int N;std::vector<std::vector<std::pair<int,int>>> ans;std::vector<std::pair<int,int>> temp;void recursion(int row, int col);bool isValid(int row, int col, std::vector<std::pair<int,int>>& temp);
};
NQueen::NQueen(int N) : N(N)
{
}void NQueen::printAns()
{recursion(0, 0);std::vector<std::vector<int>> board(N, std::vector<int>(N, 0));for (const auto& it : ans){for (const auto& jt : it){board[jt.first][jt.second] = 1;}for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (board[i][j] == 1) cout << "Q ";else cout << "* ";}cout << endl;}for (int i = 0; i < 2 * N - 1; i++){cout << "=";}cout << endl;board.clear();board.resize(N, std::vector<int>(N, 0));}}void NQueen::recursion(int row, int col)
{if (row == N){ans.push_back(temp);return;}for (int i = 0; i < N; i++){if (isValid(row, i, temp)){temp.push_back(std::make_pair(row, i));recursion(row + 1, col);temp.pop_back();}}
}bool NQueen::isValid(int row, int col, std::vector<std::pair<int, int>>& temp)
{for (const auto& it : temp){if (it.first == row || it.second == col || abs(it.first - row) == abs(it.second - col)){return false;}}return true;
}

二,位运算版本

前置知识

可以看下我的博客有关于位运算的那几节。

位运算实现加减乘除 

位图的学习

位运算的骚操作

首先我应该明白int类型数字底层是二进制数字0和1的组合。

int类型4字节,32bit。

思路

根据要求可以知道每行最多一个皇后,而又是递归,递归时行数row要更新加一。所以行上面没有限制,再后面temp.push_back()时只需要考虑列和斜对角的限制。

利用数字bit位上1和0来表示该位置能否放置皇后,跟我之前字符串的递归子序列中标记数组一样的功能。

同时利用位运算来更新限制。

列和斜对角线的影响在本层递归放置皇后后,进行更新限制。利用&和|逻辑运算合并这些限制。

通过位移来实现斜对线的更新

直接上代码

优势

为什么更快,虽然递归是通过值传递来传递影响但是位运算太快,弥补这上面的缺陷。

代码         

注释版

// 递归求解 N 皇后问题的函数
// row: 当前正在处理的行号
// left: 表示从左上到右下对角线方向上的冲突信息,使用位运算存储
// right: 表示从右上到左下对角线方向上的冲突信息,使用位运算存储
// col: 表示列方向上的冲突信息,使用位运算存储
void NQueen::recursion2(int row, int left, int right, int col)
{// 当 row 等于 N 时,说明已经成功放置了 N 个皇后,找到了一个解if (row == N){// 将当前的皇后放置方案添加到结果集合 ans 中ans.push_back(temp);// 回溯,结束当前递归调用return;}// 计算当前行所有不能放置皇后的位置// left | right | col 是将三个方向的冲突信息进行按位或运算// 得到的结果中,为 1 的位表示该位置不能放置皇后int limit = left | right | col;// 遍历当前行的每一列for (int i = 0; i < N; i++){// 检查当前位置 (row, i) 是否可以放置皇后// isValid 函数用于判断该位置是否与已放置的皇后冲突if (isValid(limit, i)){// 如果该位置可以放置皇后,将其添加到临时方案 temp 中temp.push_back(std::make_pair(row, i));// 计算下一行在各个方向上的冲突信息// (left | (1 << i)) << 1: 将当前列的左对角线冲突信息更新// 1 << i 表示将 1 左移 i 位,得到当前列的位置信息// 与 left 按位或运算后,再左移一位,表示下一行的左对角线冲突int _left = (left | (1 << i)) << 1;// (right | (1 << i)) >> 1: 将当前列的右对角线冲突信息更新// 与 left 类似,只不过是右移一位,表示下一行的右对角线冲突int _right = (right | (1 << i)) >> 1;// (col | (1 << i)): 将当前列的列冲突信息更新// 表示该列已经被占用int _col = (col | (1 << i));// 递归调用 recursion2 函数,处理下一行recursion2(row + 1, _left, _right, _col);// 回溯操作,撤销当前选择// 将该位置从临时方案 temp 中移除,尝试其他可能的位置temp.pop_back();}}
}
class NQueen
{
public:NQueen(int N);void printAns();void printAnsByBit();~NQueen() = default;
private:int N;std::vector<std::vector<std::pair<int,int>>> ans;std::vector<std::pair<int,int>> temp;void recursion(int row, int col);void recursion2(int row, int left, int right, int col);bool isValid(int row, int col, std::vector<std::pair<int,int>>& temp);void moveBit(int&, int);bool isValid(int, int);
};
void NQueen::printAnsByBit()
{recursion2(0, 0, 0, 0);std::vector<std::vector<int>> board(N, std::vector<int>(N, 0));for (const auto& it : ans){for (const auto& jt : it){board[jt.first][jt.second] = 1;}for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (board[i][j] == 1) cout << "Q ";else cout << "* ";}cout << endl;}for (int i = 0; i < 2 * N - 1; i++){cout << "=";}cout << endl;board.clear();board.resize(N, std::vector<int>(N, 0));}}void NQueen::printAnsByBit()
{recursion2(0, 0, 0, 0);std::vector<std::vector<int>> board(N, std::vector<int>(N, 0));for (const auto& it : ans){for (const auto& jt : it){board[jt.first][jt.second] = 1;}for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (board[i][j] == 1) cout << "Q ";else cout << "* ";}cout << endl;}for (int i = 0; i < 2 * N - 1; i++){cout << "=";}cout << endl;board.clear();board.resize(N, std::vector<int>(N, 0));}}
http://www.dtcms.com/wzjs/91573.html

相关文章:

  • 淘客网站怎么备案大泽山seo快速排名
  • 移动版网站建设百度一下就会知道了
  • 军队营房基础建设网站互联网全网推广
  • 设计的商城网站建设学做电商需要多少钱
  • 上海企业网站设计制作百度云app下载安装
  • 猪八戒网仿照哪个网站做的刷神马seo排名首页排名
  • 网站建设的基本教程全网seo
  • 莆田seo接单什么是seo搜索优化
  • 上海网上做鸭子的网站临沂网站seo
  • 怎样做网站的优化工作软文发布
  • 常州网站建设专业的公司长春网站建设平台
  • 阿里云的网站建设方案百度seo软件优化
  • 网站建设成都公司网站建设找哪家好
  • 微网站怎么做拉新推广平台
  • 免费微商城平台seo优化评论
  • wordpress多站点注册页灰色词优化培训
  • 铜川做网站电话中囯军事网
  • 校园网站建设软件品牌网站建设解决方案
  • 小制作小发明简单做法青岛自动seo
  • 网站域名如何更换成功的软文营销案例
  • 太原网站建设公司招聘网页制作的软件有哪些
  • 福建seo网站数字化营销怎么做
  • 网站开发需要什么基础知识搜索平台
  • 有没有傻瓜式建设网站河北seo人员
  • 免费静态网站托管百度文库首页
  • 个人网页模板网站郑州专业网站建设公司
  • 建一个营销网站的步骤龙华线上推广
  • pdf怎么做电子书下载网站汽车营销策划方案ppt
  • 网站开发需要的资源怎么建立一个自己的网站
  • 关于茶文化网站建设的背景如何搭建自己的网站