博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【康托展开】
阅读量:6998 次
发布时间:2019-06-27

本文共 898 字,大约阅读时间需要 2 分钟。

康托展开

首先我们知道对于一个有n个元素的集合,有

\[\sum_{i=1}^n A_{n}^i =n!\]

我们将该集合全排列按字典序从小到大排序

那么我们就可以用一个数x表示该集合的某个排列在全排列中的位置

显然变化的最高位(记作\(maxn\))上的数每增加1,后面的\((maxn-1)\)位就跑了一次全排列,也就是整个排列变化了\((n-1)!\)次,对于后面的数位我们依此类推,访问过的数字不用再管,因为我们只关心局部的相对大小关系

最后因为位置从1计数,\(++x\)

void cntur(){    memset(vis,0,sizeof(vis));long long x=0;    for(int i=n;i;--i) scanf("%d",&cup[i]);    for(int i=n-1;i;--i){        int cnt=0;        for(int j=1;j

康托展开的逆运算

由于康托展开是集合排列同连续整数的一一映射,我们可以用已知的康托展开求原排列

void recntur(){    memset(vis,0,sizeof(vis));    long long x;scanf("%lld",&x);--x;    for(int i=n-1;i;--i){        int tmp=x/fac[i],cnt=0;x%=fac[i];        for(int j=1;j<=n;++j){            if(!vis[j]) ++cnt;            if(cnt>tmp){cup[i+1]=j,vis[j]=1;break;}        }    }for(int i=1;i<=n;++i) if(!vis[i]){cup[1]=i;break;}    for(int i=n;i;--i) printf("%d ",cup[i]);puts("");    return;}

模板题:

转载于:https://www.cnblogs.com/AH2002/p/9576909.html

你可能感兴趣的文章
驰骋工作流引擎设计系列02
查看>>
Spring Security源码分析十:初识Spring Security OAuth2
查看>>
HDOJ 2087 KMP算法
查看>>
【转载】erlang 如何自定义 behaviour
查看>>
apache tomcat 集群 负债均衡 部署
查看>>
一步一步学Ruby(四):Ruby标准类型
查看>>
Node.js + WebSocket 实现的简易聊天室
查看>>
JSTL标签库之fn标签
查看>>
mtu检测
查看>>
在无法改动bs架构的基础上,添加新的功能(2) 浏览器
查看>>
Android 应用程序只运行一个实例
查看>>
代码整洁
查看>>
ffmpeg cmd
查看>>
网络监控
查看>>
java创建多线程的两种方法
查看>>
财务收支问题
查看>>
ADF 客户端代码调用服务器方法
查看>>
C++输入cin详解
查看>>
java与openssl的rsa算法互用
查看>>
Python strip lstrip rstrip使用方法
查看>>