【ACM】与全排列相关的STL函数 prev_permutation next_permutation
排列 与 全排列
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。
当m=n时所有的排列情况叫全排列。如果这组数有n个,那么全排列数为n!个。
对于全排列的求解可以使用递归,这里介绍几个方便的函数(),得到全排列。
对于序列{ 'a' , 'b' , 'c' }(之后为了方便,不打单引号,嘻嘻),每一个元素都比后面的小,按照字典序列,固定a之后,a比b,c都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。
头文件:#include <algorithm>
prev_permutation(start,end) “上一个排列组合”
- 函数模板:prev_permutation(arr, arr+size)
- 说明:arr数组名,size数组元素个数
- 返回值:bool型,当 当前序列 不存在上一个排列时,返回false,否则返回true,排列好的元素储存在数组中(所以想要看到全部的排列情况需要不断地输出数组里的元素)
- 注意:在使用前需要对待使用的数组按照降序排列,否则只会输出该序列之后的排列情况。
next_permutation(start,end) “下一个排列组合”
- 函数模板:next_permutation(arr,arr+size)
- 说明:arr数组名,size数组元素个数
- 返回值:bool型,当 当前序列 不存在下一个排列时,返回false,否则返回true,排列好的元素储存在数组中(所以想要看到全部的排列情况需要不断地输出数组里的元素)
- 注意:在使用前需要对待使用的数组按照升序排列,否则只会输出该序列之后的排列情况。
#include <iostream>
#include <algorithm>
using namespace std;
int main ()
{int arr[] = {3,2,1};cout<<"用prev_permutation对3 2 1的全排列"<<endl;do{cout << arr[0] << ' ' << arr[1] << ' ' << arr[2]<<'\n';}while ( prev_permutation(arr,arr+3) ); ///获取上一个较大字典序排列,如果3改为2,只对前两个数全排列int arr1[] = {1,2,3};cout<<"用next_permutation对1 2 3的全排列"<<endl;do{cout << arr1[0] << ' ' << arr1[1] << ' ' << arr1[2] <<'\n';}while ( next_permutation(arr1,arr1+3) ); ///获取下一个较大字典序排列,如果3改为2,只对前两个数全排列///注意数组顺序,必要时要对数组先进行排序return 0;
}
现学现用:
一、杭电1027 Ignatius and the Princess II
http://acm.hdu.edu.cn/showproblem.php?pid=1027(注意while的条件)
对N个数进行全排列,从小到大,找到第M个全排列然后输出
运用上面的next_permutation函数,可以很快解决,但是在使用do-while循环的时候要注意括号里的条件
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int a[maxn];void permutation(int n,int m)
{int count=0;do{count++;}while( count<m && next_permutation(a,a+n) );
}int main ()
{int N,M;while(scanf("%d%d",&N,&M)!=EOF){for(int i=0;i<maxn;i++){a[i]=i+1;}permutation(N,M);for(int i=0;i<N;i++){if(i!=N-1)printf("%d ",a[i]);elseprintf("%d\n",a[i]);}}return 0;
}
上面这幅图的判断条件是:
while( count<m && next_permutation(a,a+n) )
这个在进行条件判断时,是先判断count的值,再来调用next_permutation函数
使用下面这串代码也可以
void permutation(int n,int m)
{int count=0;do{count++;}while( next_permutation(a,a+n) && count<m-1 );
}
上面这幅图的判断条件是:
while( next_permutation(a,a+n) && count<m-1 )
先count+1然后调用next_permutation函数。如给出的样例,6,4。当count到3的时候,在来进行判断时,判断条件有两个语句,所以是先执行next_permutation,再判断count,所以,count应小于m-1。
二、杭电1716 排序2
http://acm.hdu.edu.cn/showproblem.php?pid=1716
(我觉得掌握了上面的两个函数,那么1716的难点在于输出格式)
需要设置一个变量pre来记录下一个全排列的a[0]和之前的a[0]是否一样。
如果a[0]=0,则跳过
同一行中每个四位数间用空格分隔,每组输出数据间空一行
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int a[maxn];
int main ()
{int count,pre,t=0,flag;while(1){count=0;flag=0;for(int i=0;i<4;i++){scanf("%d",&a[i]);if(!a[i])++count;}if(count==4)return 0;if(t) printf("\n");t=1;flag=1;pre=a[0];do{if(a[0]==0)continue;if(flag){printf("%d%d%d%d",a[0],a[1],a[2],a[3]);flag=0;}else if(pre==a[0]){printf(" %d%d%d%d",a[0],a[1],a[2],a[3]);}else{printf("\n%d%d%d%d",a[0],a[1],a[2],a[3]);}pre=a[0];}while( next_permutation(a,a+4) );printf("\n");}return 0;
}
三、杭电OJ 5055 Bob and math problem
http://acm.hdu.edu.cn/showproblem.php?pid=5055
该题是要在全排列中找到最大的奇数,所以和上面两题用的函数不一样,先让数组中的数字按照降序排列(从大到小),然后用prev_permutation(a,a+n),加一些条件限制,注意换行,找到的第一个符合条件的,就是answer,然后break,退出循环,用一个flag变量标记,如果在循环里没有输出,则表明没有找到符合条件的数,那么在退出循环之后,输出-1
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 105;
int a[maxn];
bool cmp(int a,int b)
{return a>b;
}int main ()
{int n,i,flag;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);sort(a,a+n,cmp);flag=0;do{if(a[n-1]%2==1 && a[0]!=0){for(i=0;i<n;i++){printf("%d",a[i]);}printf("\n");flag=1;break;}}while( prev_permutation(a,a+n) );if(!flag){printf("-1\n");}}return 0;
}
方法二解5055 https://blog.csdn.net/CSDN___CSDN/article/details/84893748
四、POJ 1146 ID Codes
本题关键在于读懂题意,要求输出的是下一个全排列,如果下一个全排列不存在,则输出No Successor
http://poj.org/problem?id=1146
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1000000;
char str[maxn];
int main ()
{int len;while(scanf("%s",str)!=EOF){if(strcmp(str,"#")==0)return 0;len=strlen(str);if(next_permutation(str,str+len))printf("%s\n",str);elseprintf("No Successor\n");}return 0;
}
五、POJ 3187 Backward Digit Sums
http://poj.org/problem?id=3187
就通过前面几个得到规律,按照这种倒三角的加法
一个数:1 -----> 1*a[0]
两个数:1 1 -------> 1*a[0]+1*a[1]
三个数:1 2 1 --------> 1*a[0]+2*a[1]+1*a[2]
四个数:1 3 3 1 ----------->1*a[0]+3*a[1]+3*a[2]+1*a[3]
是杨辉三角,所以先储存杨辉三角,再用next_permutation函数,我就是手动推倒了几个,大佬应该一眼就看出来了吧,
嘻嘻嘻,我是呆瓜
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[12],k[12][12];
void fun()
{int i,j;for(i=1;i<=10;i++){for(j=1;j<=i;j++){if(i==1 || j==i || j==1)k[i][j]=1;elsek[i][j]=k[i-1][j]+k[i-1][j-1];}}
}int main ()
{int i,j,N,M,sum;fun();while(scanf("%d%d",&N,&M)!=EOF){for(i=0;i<N;i++){a[i]=i+1;}do{sum=0;for(i=0,j=1;i<N,j<=N;i++,j++)sum+=(a[i]*k[N][j]);if(sum==M)break;}while(next_permutation(a,a+N));for(i=0;i<N;i++)printf("%d ",a[i]);printf("\n");}return 0;
}
之后会推出用递归的方法求解全排列,
还有,如果在遇到全排列的题会做相应的补充
有错的话,希望读者及时指正
相关文章:

虚拟机无法使用网卡桥接模式
重装了好几遍操作系统,换了两个虚拟机,差点怀疑人生…… 最终的原因竟然是win10!!! 1.执行WINR 输入services.msc,打开服务管理器(回车)。 2.找到Device Install Service服务 启动此…

Azure自动化部署运维浅谈
本次来谈一谈如何在Azure中实现一些简单的自动化运维的需求,一般来讲自动化运维我们通过很多第三方的工具平台实现,比较流行的目前有很多,比如老牌的chef, puppet,新兴的PowerShell DSC, ansible。这些应该都是耳熟能详的了。那么在Azure平台…
NDK/JNI demo ( 五 ) ORB_SLAM2在Android上的移植过程
Android平台搭建和NDK环境配置 Android移植基础 NDK是集成的Android中调用C代码的工具包,核心是JNI(Java Native Interface)技术,具体这里略过不表。只说说NDK开发的基本步骤: 1. 编写Java代码:在Java中定义…

[Nancy On .Net Core Docker] 轻量级的web框架
.net core现在已经有了大的发展,虽然笔者现在已经从事python开发,但是一直在关注.net的发展,在逛博客园的时候,发现有大家都会提到Nancy这个框架,在简单的使用之后,发现竟然是如此的简单而优雅 public clas…

【算法】【ACM】深入理解Dijkstra算法(单源最短路径算法)
Dijkstra算法是用来求解从某个源点到其他各顶点的最短路径(单源最短路径)。 下面的Dijkstra算法的讲解都是基于这个有向图,在遇到其他问题可以类比。 算法的基本思想: 把图中的定点分成两组,第一组包括已确定最短路径…

智能POS常见问题整理
智能POS预警值为小于所设的数量,H5就会变为锁定状态 智能POS查看数据库方法: 商米D1:设置-存储设备和USB-内部存储设备-浏览-winboxcash tablet.db为智能POS数据库 Winbox文件夹内,为相应logcat文件,应用出现问题时&am…
解决安卓系统写入SD卡权限问题
1.需要用户手动赋予的权限( Dangerous Permissions) 所属权限组权限日历READ_CALENDAR日历WRITE_CALENDAR相机CAMERA联系人READ_CONTACTS联系人WRITE_CONTACTS联系人GET_ACCOUNTS位置ACCESS_FINE_LOCATION位置ACCESS_COARSE_LOCATION麦克风RECORD_AUDIO…

【ACM】【STL】stack应用
C Stacks(堆栈) C Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。 操作比较和分配堆栈empty()堆栈为空则返回真…

CHUCK手把手带你搞定OPENSTACK
以下是原文链接:http://blog.oldboyedu.com/openstack/转载于:https://blog.51cto.com/bovin/1858198

JVM基础面试题及原理讲解
2019独角兽企业重金招聘Python工程师标准>>> 本文从 JVM 结构入手,介绍了 Java 内存管理、对象创建、常量池等基础知识,对面试中 JVM 相关的基础题目进行了讲解。 写在前面(常见面试题) 基本问题 介绍下 Java 内存区域…
SLAM前端 ---------特征提取之ORB(ORB与SIFT与SURF)
ORB 论文翻译: 一种特征匹配替代方法:对比SIFT或SURF 1.ORB特征简介 ORB是Oriented FAST and Rotated BRIEF(oFAST and rBRIEF)的简称,ORB的名字已经说明了其来源,其实ORB特征是采用FAST方法来检测提取特…

oracle 内存分配和调优 总结
一直都想总结一下oracle内存调整方面的知识,最近正好优化一个数据库内存参数,查找一些资料并且google很多下。现在记录下来,做下备份。 一、概述: oracle 的内存可以按照共享和私有的角度分为系统全局区…

【ACM】Doubly Linked List(STL list)
题目链接:https://vjudge.net/problem/Aizu-ALDS1_3_C 这一题一开始的时候想的是用vector,超时 #include <iostream> #include <stack> #include <cstdio> #include <cstring> #include <queue> #include <vector>…

IOS获取焦点页面上移问题
var u navigator.userAgent; var flag; var myFunction; var isIOS !!u.match(/(i1;( U;)? CPU.Mac OS X/); if (isIOS) { document.body.addEventListener(focusin, () > { //软键盘弹起事件flag true;clearTimeout(myFunction); }) document.body.addEventListener(f…
SLAM之特征匹配(二)————RANSAC--------翻译以及经典RANSAC以及其相关的改进的算法小结
本文翻译自维基百科,英文原文地址是:http://en.wikipedia.org/wiki/ransac RANSAC是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数…

【ACM】树 小结
树是一种表达层级结构的数据结构,也是实现高效算法与数据结构的基础。 学习之前的基础:数组,循环处理,结构体,递归函数。 树:由结点(node)和连接结点的边(edge…

【cocos2d-js官方文档】九、cc.loader
概述 原来的cc.Loader被改造为一个单例cc.loader,采用了插件机制设计,让loader做更纯粹的事。 各种资源类型的loader可以在外部注册进来,而不是直接将所有的代码杂揉在cc.Loader中,更好的方便管理以及用户自定义loader的创建。 cc…

更换VC后DDC提示证书不可用
问题描述:客户环境由Windows VC更换成Linux VC后,DDC提示证书不可用问题原因:因为VC更换后,存储在DDC数据库HostingUnitServiceSchema.HypervisorConnectionSSLThumbprint表中证书指纹信息和新得VC证书指纹信息不匹配。解决方法&a…
尺度空间理论与图像金字塔
我们之所以决定使用卷积后的特征是因为图像具有一种“静态性”的属性。也就是说使用卷积就是为了提取显著特征,减少特征维数,减少计算量。 在对图像进行卷积操作后的只管现象:图像变得模糊了,可是我们依然能够分辨出是什么&#x…

【ACM】 multiset 的 一些应用
一、The kth great number 题目链接:https://vjudge.net/problem/HDU-4006 用set写超时 (在VJ里,用C显示Compilation Error,选择G,则是TLE) #include <iostream> #include <set> #include &…

apache2.2 做后端,增加真实ip到日志中
apache2.2使用mod_remoteip模块 一.安装 wget https://github.com/ttkzw/mod_remoteip-httpd22/raw/master/mod_remoteip.c/usr/local/apache/bin/apxs -i -c -n mod_remoteip.so mod_remoteip.c 二.添加Apache配置vi /usr/local/apache/conf/httpd.confInclude conf/extra/htt…

高可用方案系统架构
2019独角兽企业重金招聘Python工程师标准>>> 高可用方案 系统架构 转载于:https://my.oschina.net/qiongtaoli/blog/3007587
OpenCV3.2.0+VS2017在window10开发环境配置记录
本机环境:win10 64位 OpenCV3.2.0 Visual Studio 2017 最后结果,亲测可用OpenCV官方下载地址: http://opencv.org/releases.html#本人选择opencv3.2.0基于Windows平台。读者根据自己需要选择合适版本及平台下载。 选择window版本的opencv下载…

C++vector迭代器失效的问题
转载:http://blog.csdn.net/olanmomo/article/details/38420907 转载:http://blog.csdn.net/stpeace/article/details/46507451 转载:http://www.cnblogs.com/xkfz007/articles/2509433.html 转载:http://www.cnblogs.com/BeyondAnyTime/archive/2012/08/13/2636375.html 有这样…

【HDU】1251统计难题 (字典树:二维数组,结构体数组,链表,map)
使用二维数组或者结构体数组都可以,但是在计数的时候有一点点小区别 一、结构体数组 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> typedef long long ll; using namespace…

Jmeter干货 不常用却极其有用的几个地方
1. Jmeter测试计划下Run Thread Groups consecutively 表示序列化执行测试计划下所有线程组中的各个请求 如下图配置,新建的测试计划中,不默认勾选此项, 而享用Jmeter做接口自动化测试的同学们,会发现一个问题是,可能多…
图像滤波总结(面试经验总结)
目录 图像平滑处理,6种滤波总结的综合示例 【盒式滤波、均值滤波、高斯滤波、中值滤波、双边滤波导向滤波】 1-图像滤波 2-代码演示 3-显示结果 4-程序说明 5 角点检测(Harris,Fast,surf) 图像平滑处理,6种滤波总结的综合示…

【小贴士】DEV 多行注释
多行注释 Ctrl / 取消多行注释 Ctrl ,

JSP+Servlet基础一
2019独角兽企业重金招聘Python工程师标准>>> JSP中的指令: 格式:<%指令的名称(page,taglib,include...) 属性属性值%> 指令中的page:用于整个页面,定义与页面相关的属性。page属性一共有13个。 1、常…

Chameleon跨端框架——壹个理想主义团队的开源作品
文章较长,信息量很大,请耐心阅读,必然有收获。下面正文开始~背景解决方案原理久经考验生产应用举例易用性好多态协议学习成本低渐进式接入业内对比后期规划理想主义历经近20个月打磨,滴滴跨端方案chameleon终于开源了github.com/d…