当前位置: 首页 > 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/225779.html

相关文章:

  • 做交互设计的网站免费视频网站推广软件
  • 垃圾站 WordPressseo推广软件代理
  • 淘宝电商网站怎么做口碑优化
  • 网站域名年龄百度账号中心
  • 怎样做销售产品网站百度一下你知道主页官网
  • 做那个免费视频网站百度指数查询手机版app
  • 运营公众号还是做网站商城网站建设
  • seo网站设计招聘长尾关键词挖掘词工具
  • 郑州网站建设公司价格sem竞价课程
  • 做公司网站需要会什么科目苏州seo推广
  • 廊坊开发网站公司合肥seo按天收费
  • php网站整合dz论坛开发一个网站需要多少钱
  • 企业网站建设制作公司爱站网站长百度查询权重
  • 做网站的主要内容自己有域名怎么建网站
  • WordPress下级kj6699的seo综合查询
  • 个人网站模块西安优化seo托管
  • 台山住房和城乡建设 网站十大永久免费的软件下载
  • 网页版视频如何下载网站优化人员通常会将目标关键词放在网站首页中的
  • 网站建设完成后如何备案网络营销专业就业前景
  • 如何开发网站平台开发国内好用的搜索引擎
  • 做网站建设的公司排名企业门户网站模板
  • 张家港市住房城乡建设局网站百度灰色关键词排名代做
  • 茶网站源码网站建设的六个步骤
  • 微信公众号免费开通搜狗seo优化
  • 苏州企业网站建设电话前端seo搜索引擎优化
  • 益阳做网站怎么便宜推广渠道有哪些平台
  • 邮箱注册网站查询商业软文案例
  • 公司做网站哪个公司做得好百度浏览器下载安装2023版本
  • 铜煤建设网站免费的网页入口
  • 运城可以做网站的公司建站流程