判断全排列的出现次序
来源:互联网 发布:数据表单设计原则 编辑:程序博客网 时间:2024/06/16 13:03
假如你使用模拟全排列计数,基本会超时;
实现原理:康托展开式
X=a[n](n-1)!+a[n-1](n-2)!+…+a[i]*(i-1)!+…+a[2]*1!+a[1]*0![1]
其中a[i]为当前未出现的元素中是排在第几个(从0开始)
列如 {1,2,3} 按从小到大排列一共6个。123 132 213 231 312 321 。
输入321,让你它在全排列中是第几个,321是6;
具体代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;//斐波那契表long int fac[]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};long cantor(int s[],int n){ long int i,j,temp,num; num=0; for(i=0;i<n;i++) { temp=0;//记录几个数小于这个数 for(int j=i+1;j<n;j++) { if(s[j]<s[i])temp++;//判断几个数小于它 } num += fac[n-i-1]*temp; } return num+1;}int main(){ int a[11]={11,10,9,1,2,3,5,8,7,6,4}; cout<<cantor(a,11); return 0;}
下面还有逆康托公式;
例如 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕,你求出第96个序列是什么?
找出第96个数
首先用96-1得到95
用95去除4! 得到3余23
有3个数比它小的数是4
所以第一位是4
用23去除3! 得到3余5
有3个数比它小的数是4但4已经在之前出现过了所以第二位是5(4在之前出现过,所以实际比5小的数是3个)
用5去除2!得到2余1
有2个数比它小的数是3,第三位是3
用1去除1!得到1余0
有1个数比它小的数是2,第二位是2
最后一个数只能是1
所以这个数是45321
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<windows.h>#include<cmath>using namespace std;int res[12];long int fac[]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};long cantor(int s[],int n){ long int i,j,temp,num; num=0; for(i=0;i<n;i++) { temp=0;//记录几个数小于这个数 for(int j=i+1;j<n;j++) { if(s[j]<s[i])temp++;//判断几个数小于它 } num += fac[n-i-1]*temp; } return num+1;}void uncantor(int x,int k){ memset(res,0,sizeof(res)); int i,j,l,t; int h[12]={0}; for(i=1;i<=k;i++) { t=x/fac[k-i]; x-=t*fac[k-i]; for(j=1,l=0;l<=t;j++) { if(!h[j]) { l++; } } j--; h[j]=1; res[i-1]=j; }}int main(){ int a[11]={11,10,9,1,2,3,5,8,7,6,4}; cout<<cantor(a,11)<<endl; uncantor(cantor(a,11)-1,11);//利用上面算出来的序号;输出的正好是那个序列 for(int i=0;i<11;i++) { cout<<res[i]<<" "; } cout<<endl; return 0;}
0 0
- 判断全排列的出现次序
- 颠倒单词的出现次序
- 判断字符串是否包含另一字符串的全排列
- 字符串的全排列问题(一)——无重复出现字符的排列
- 字符串的全排列
- 数字的全排列
- 字符串的全排列
- 字符的全排列
- 数组的全排列
- 全排列的学习
- 12345的全排列
- 全排列的序号
- 字符串的全排列
- 整数的全排列
- 整数的全排列
- 全排列的输出
- 数的全排列
- 优雅的全排列
- 从系统相册选取视频并获得视频的缩略图(取消自动播放)
- hostapd修改Beacon和Probe Response帧
- C++对C的const扩展
- 堆排序
- 扩展欧几里得算法与模乘逆元的程序
- 判断全排列的出现次序
- 【bzoj4597】[Shoi2016]随机序列 线段树
- 定时器(quartz)的使用
- 国内下载android源码镜像地址及方法
- when i run server i got "name 'http' is not defined" after import http.server then i got this "no mo
- [JavaScript] 6.JS 常见内置对象
- jbpm4.4审批实例
- 使用GPUImage渲染图片教程
- 解决ViewPager嵌套,滑动冲突