遇到这个算法是在大牛写的10行的8皇后问题中,下面首先给出这个10行就解决了8皇后的NB代码,我目前还是没有看懂对于皇后不在同一列的判断,因为他巧妙的用了移位操作

#include<iostream>
#include<algorithm>
#include<bitset>
#include<numeric>
#include<utility>
int main() {
int i = 0;
for (int queens[] = {0,1,2,3,4,5,6,7}; std::next_permutation(queens,queens+8);)
if ((std::bitset<15>(std::accumulate(queens,queens+8, std::make_pair(0, 0), [](std::pair<int, int> a, int b){return std::make_pair((1<<(b+a.second))|a.first,a.second+1);}).first).count() == 8) && (std::bitset<15>(std::accumulate(queens, queens+8, std::make_pair(0, 0), [](std::pair<int, int> a, int b){return std::make_pair((1<<(7+b-a.second))|a.first, a.second+1);}).first).count() == 8))
std::cout << ++i << " : " << queens[0] << queens[1] << queens[2] << queens[3] << queens[4] << queens[5] << queens[6] << queens[7] << std::endl;
return 0;
}

在上面的代码中,用next_permutation的原因是可以生成用0~7表示的所有序列。然后我们用if语句判断此时的序列(也就是每一个列序列)是否符合条件,要是符合就输出,否则就跳过,相当于用了打表的方式,列出所有可能的结果再寻找符合条件的。next_permutation的作用就是生成这所有的可能序列。

next_permutation的作用是:生成下一个较大的序列。perv_permutation的作用是生成下一个较小的序列。

以next_permutation举个例子:

我们用(a1 a2 … am)来表示m个数的一种序列。设序列pn=<3 6 4 2>,根据定义可算得下一个序列pn+1=<4 2 3 6>。观察pn可以发现,其子序列<6 4 2>已经为减序,那么这个子序列不可能通过交换元素位置得出更大的序列了,因此必须移动最高位3(即a1)的位置,且要在子序列<6 4 2>中找一个数来取代3的位置。子序列<6 4 2>中6和4都比3大,但6大于4。如果用6去替换3得到的序列一定会大于4替换3得到的序列,因此只能选4。将4和3的位置对调后形成排列<4 6 3 2>。对调后得到的子序列<6 3 2>仍保持减序,即这3个数能够生成的最大的一种序列。而4是第1次作为首位的,需要右边的子序列最小,因此4右边的子序列应为<2 3 6>,这样就得到了正确的一个序列pn+1=<4 2 3 6>。

下面我们用代码验证一下

#include<iostream>
#include<algorithm>
#include<vector> using std::cout;
using std::cin;
using std::endl; int main(int argc,char *argv[])
{
int chs[] = {3,6,4,2};
int count = sizeof(chs)/sizeof(*chs);
std::vector<int> vchs(chs,chs+count); std::next_permutation(vchs.begin(),vchs.end());
for(auto u:vchs) cout << u << " ";cout << endl;
return 0;
}

下面看看它的实现

#include<iostream>
#include<algorithm>
#include<string> using std::cout;
using std::cin;
using std::endl; int main(int argc,char *argv[])
{
for(std::string str;cin >> str ;) {
//如果为空,直接结束
if(str.empty()) {
continue;
}
//长度小于等于一的没有子序列
if(str.length() <= 1) {
cout << "No " << endl;
}
std::string::iterator iPivot = str.end(),iNewHead;
//从最后往前找递减序列,直到找到
for(--iPivot;iPivot != str.begin();--iPivot) {
if(*(iPivot-1) <= *iPivot) {
break;
}
}
//如果一直找到开头,就说明此时已经是一个递减的序列,不会再有比它大的序列了
if(iPivot == str.begin()) {
cout << "No" << endl;
}
iPivot--;
//否则从右侧序列中找小于刚才的iPivot序列的
for(iNewHead = iPivot+1;iNewHead != str.end();++iNewHead) {
if(*iNewHead < *iPivot) {
break;
}
}
//然后交换它们的元素
std::iter_swap(iPivot,--iNewHead);
//然后将后面的翻转
std::reverse(iPivot+1,str.end());
cout << str << endl;
}
return 0;
}

c++ 算法 next_permutation的更多相关文章

  1. stl算法:next_permutation剖析

    在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组数据的全排列.但是怎么用,原理如何,我做了简单的剖析. 首先查看stl中相关信息.函数原型: templa ...

  2. generating permunation——全排列(算法汇总)

    本文一共提供了4种全排列的方法,包括递归非字典序版本.递归字典序版本.标准库版本和BFS字典序版本,当然BFS非字典序实现相对于BFS字典序版本更加简洁,稍加修改即可. 说明:递归版本基于网上现有代码 ...

  3. 编程艺术第十六~第二十章:全排列/跳台阶/奇偶调序,及一致性Hash算法

    目录(?)[+]   第十六~第二十章:全排列,跳台阶,奇偶排序,第一个只出现一次等问题 作者:July.2011.10.16.出处:http://blog.csdn.net/v_JULY_v. 引言 ...

  4. 2.1.12 Next Permutation 下一个字典序数组

    对当前排列从后向前扫描,找到一对为升序的相邻元素,记为i和j(i < j).如果不存在这样一对为升序的相邻元素,则所有排列均已找到,算法结束:否则,重新对当前排列从后向前扫描,找到第一个大于i的 ...

  5. generating permunation

    generating permunation——全排列(算法汇总) #include <iostream> #include <string> #include <vec ...

  6. 全排列问题(递归&非递归&STL函数)

    问题描述: 打印输出1-9的所有全排序列,或者打印输出a-d的全排列. 思路分析: 将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去. 比如:1 2 3 为例首先 ...

  7. LeetCode(31) Next Permutation

    题目 Implement next permutation, which rearranges numbers into the lexicographically next greater perm ...

  8. LeetCode(60) Permutation Sequence

    题目 The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of th ...

  9. 【04NOIP普及组】火星人(信息学奥赛一本通 1929)(洛谷 1088)

    [题目描述] 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类 ...

随机推荐

  1. 直接取PHP二维数组里面的值

    具体是这样的,如下一个二维数组,是从库中读取出来的. $user = array( 0 => array( 'id'    => 1, 'name'  => '张三', 'email ...

  2. Win10删除电脑3D对象等7个文件夹

    把下面几个注册表项依次删除掉 "图片"文件夹:[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Expl ...

  3. FastAPI(39)- 使用 CORS 解决跨域问题

    同源策略 https://www.cnblogs.com/poloyy/p/15345184.html CORS https://www.cnblogs.com/poloyy/p/15345871.h ...

  4. Superedge的新特性和未来之路

    作者 王冬,腾讯云高级研发工程师,专注于Kubernetes.容器等云原生领域,SuperEdge 核心开发人员,现负责腾讯云边缘容器TKE Edge私有化相关工作. 背景 2021年9月27号,,在 ...

  5. 一次OutOfMemoryError: GC overhead limit exceeded

    现象: 由于需要将mysql表中的过期数据在凌晨定时读取出过滤后转入到MongoDB,一个转换SQL达到百行,而且有几十个,集中运行后程序反馈异常: Handler dispatch failed; ...

  6. mysql创建用户及赋予某用户权限(附带基础查看表内容)

    首先登陆mysql 一:show databases;  展示所有数据库(root用户下) 二:use xxx (数据库名)使用use选择数据库 三:show xxx   查看数据库中的表 四:des ...

  7. Arcscene教程

    ​ ​ ​ ​ ​ ​ ​ ​ ​ ​​ ​ 筛选​ ​ ​ ​ ​ ​ ​ ​ 看不清的话可以进行如下操作:右键-->属性-->符号系统-->把高程前面的对号取消-->添加- ...

  8. 【日志技术专题】「logback入门到精通」彻彻底底带你学会logback框架的使用和原理(入门介绍篇)

    技术介绍 什么是 logback? Logback为取代 log4j 而生.Logback 由 log4j 的创立者 Ceki Gülcü设计.以十多年设计工业级记录系统的经验为基础,所创建的logb ...

  9. Java(29)集合四Collections

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228439.html 博客主页:https://www.cnblogs.com/testero ...

  10. cs224n 2019

    视频链接 相关资源 Notes 笔记下载 笔记2 需要挂梯子,不然不显示图片,如果用ssr,要调到全局模式 转自:bitJoy CS224N(1.8)introduction and Word Vec ...