【数学】康托展开 && 康托逆展开
(7.15)康托展开,就是把全排列转化为唯一对应自然数的算法。它可以建立1 ~ n的全排列与[1, n!]之间的自然数的双向映射。
1、康托展开:
尽管我并不清楚康托展开的原理何在,这个算法的过程还是比较好记的。正确性之后有机会询问下学长。
如果从1开始给全排列的排名从大到小编号的话(从0开始也可,建立的是与[0, n!-1]的映射,本质相同),定义rk为排名,a是排列数组,排列有n位(最低位是第0位),那么有公式
rk - 1 = cnt[n-1] * (n-1)! + cnt[n-2] * (n-2)! + ... + cnt[0] * 0!
其中cnt数组的含义是未统计的数字中,小于a[i]的数字有多少个。
举例:计算排列3 4 2 1对于{1, 2, 3, 4}的排名
首先取出最高位(第三位),小于数字3的数有两个,所以cnt[3] = 2,rk += 2 * 3!,rk = 12。
然后取出4,小于4的数有三个,但是3已经被统计过了,所以cnt[2] = 2,rk += 2 * 2!,rk = 16.
取出2,小于2的只有1,cnt[1] = 1,rk += 1 * 1!,rk = 17。
最后由于除第0位本身外已经没有数了,cnt[0]恒等于0。所以3 4 2 1的排名为18。
代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- int f[10], n;
- bool vis[10];
- int KtSplay(int *a) { //康托展开,返回的[1, n!]之间的数
- int rk = 0;
- cal();
- for (int i = 1; i <= n; ++i)
- vis[i] = 0;
- for (int i = n - 1; i >= 0; --i) {
- int u = a[i], cnt = 0;
- for (int i = 1; i < u; ++i)
- if (!vis[i]) ++cnt;
- rk += cnt * f[i];
- vis[u] = true;
- }
- return rk + 1;
- }
- int a[10];
- int main() {
- cin >> n;
- for (int i = n - 1; i >= 0; --i)
- cin >> a[i];
- cout << KtSplay(a);
- }
(先咕掉逆展开)
(先补一点)
康托展开的逆过程,就是依照排名来查询排列。
首先把排名-1(突然发现这样有点麻烦,可能从0开始编排名号更合理,大家看得懂就好)。然后我们考虑康托展开的过程,用带余除法的方式确定每一位数字的排名,进而得到这个数。
比如我们要计算{1, 2, 3, 4}排列中排第18的排列。
第三位(最高位):17/3! = 2……5,说明比该位小的数有2个,该位是3。
第二位:5/2! = 2……1,说明这一位是当前没出现的第2个,该位是4。
第三位:1/1! = 1……0,说明这一位是2。
那么最后一位是1。
所以所求排列是3、4、2、1。
代码:
- void KtResplay(int rk) {
- --rk;
- cal();
- for (int i = n - 1; i; --i) {
- int k = rk / f[i];
- int j = 0;
- while (k >= 0) {
- ++j;
- if (!vis[j])
- --k;
- }
- vis[j] = true;
- a[i] = j;
- rk = rk % f[i];
- }
- for (int i = 1; i <= n; ++i)
- if (!vis[i]) {
- a[0] = i;
- break;
- }
- return;
- }
(2019.7.16 坑填了)
【数学】康托展开 && 康托逆展开的更多相关文章
- 康托展开&&康托逆展开
康托展开 简介:对于给定的一个排列,求它是第几个,比如54321是n=5时的第120个.(对于不是1~n的排列可以离散化理解) 做法: ans=a[n]*(n-1)!+a[n-1]*(n-2)!+~~ ...
- HDU 1027 Ignatius and the Princess II(康托逆展开)
Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ( ...
- 康托展开&康托逆展开 的写法
康托展开 康托展开解决的是当前序列在全排序的名次的问题. 例如有五个数字组成的数列:1,2,3,4,5 那么1,2,3,4,5就是全排列的第0个[注意从0开始计数] 1,2,3,5,4就是第1个 1, ...
- nyoj 139——我排第几个|| nyoj 143——第几是谁? 康托展开与逆康托展开
讲解康托展开与逆康托展开.http://wenku.baidu.com/view/55ebccee4afe04a1b071deaf.html #include<bits/stdc++.h> ...
- 康托展开&逆展开算法笔记
康托展开(有关全排列) 康托展开:已知一个排列,求这个排列在全排列中是第几个 康托展开逆运算:已知在全排列中排第几,求这个排列 定义: X=an(n-1)!+an-1(n-2)!+...+ai(i-1 ...
- 康托展开+逆展开(Cantor expension)详解+优化
康托展开 引入 康托展开(Cantor expansion)用于将排列转换为字典序的索引(逆展开则相反) 百度百科 维基百科 方法 假设我们要求排列 5 2 4 1 3 的字典序索引 逐位处理: 第一 ...
- 康托展开与逆康托展开模板(O(n^2)/O(nlogn))
O(n2)方法: namespace Cantor { ; int fac[N]; void init() { fac[]=; ; i<N; ++i)fac[i]=fac[i-]*i; } in ...
- lightoj1060【康托逆展开】
可以先看些资料:http://blog.csdn.net/keyboarderqq/article/details/53388936 参考谷巨巨:http://blog.csdn.net/azx736 ...
- 康托(Cantor)展开
直接进入正题. 康托展开 Description 现在有"ABCDEFGHIJ”10个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? Input ...
随机推荐
- C#连接Access
连接数据库 string oleCon = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " + Application.Sta ...
- TCP/IP 基础知识
我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 已提交此篇文章 要说我们接触计算机网络最多的协议,那 ...
- [Luogu P3455] [POI2007]ZAP-Queries (莫比乌斯反演 )
题面 传送门:洛咕 Solution 这题比这题不懂简单到哪里去了 好吧,我们来颓柿子. 为了防止重名,以下所有柿子中的\(x\)既是题目中的\(d\) 为了方便讨论,以下柿子均假设\(b>=a ...
- Unity报错:xxx AnimationEvent has no function name specified!
参考:https://blog.csdn.net/register_man/article/details/54172778 在开发时出现了题目中的错误且有动画掉帧的情况,搜索后发现是在动画编辑器中我 ...
- 力扣 - 142. 环形链表 II
目录 题目 思路1 代码实现 思路2 代码实现 题目 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链 ...
- CSP-S 2020全国开放赛前冲刺模拟训练题1 T4 二维码
组合 首先可以考虑一个状态合法的条件,可以发现的是最后得到的矩阵一定是至少有一行或是有一列全$0$或$1$,如果把这一列或这一行删掉那么将剩下的子矩阵拼接起来又是一个子问题,同样的也是至少有一列或一行 ...
- Ubuntu 18.04 Java JDK/JRE 安装命令
安装默认版本 sudo apt install default-jdk Java 8 sudo apt install openjdk-8-jdk 如果我们在服务器上安装了多个Java版本,我们可以使 ...
- CentOS7下一键小白搭建seafile pro云盘
搭建前准备工作 vps或者云服务器,个人搭建使用建议腾讯云,公司搭建使用建议阿里云. 没有服务器的小伙伴可以下面链接进入看下,腾讯云的配置带宽会比阿里云的好点. 阿里云新人优惠服务器 腾讯云云上特惠 ...
- 内网渗透 day4-meterpreter基本命令
meterpreter基本命令 目录 1.getuid 查看当前用户 1 2.getpid 查看当前的进程id 1 3.getsystem 初步提权 1 4.ps 1.查看进程列表2.帮助我们获取pi ...
- impala-shell -o a.txt 查询中有中文时报错问题的处理
当使用impala-shell -o a.txt进入impala-shell之后,查询报错: 报错情况: Query: select * from dim_sales_dept Unknown Exc ...