康托展开模板
来源:互联网 发布:mac flamingo 编辑:程序博客网 时间:2024/05/24 15:41
讲解看这里:http://blog.csdn.net/acdreamers/article/details/7982067
康托展开表示的是当前排列在n个不同元素的全排列中的名次,康托逆展开就是根据某个排列的在总的排列中的名次来确定这个排列。注意,这个模板中康托逆展开求出的排列是一个连续序列的排列
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 100 + 10;char s[N];ll fact[N];void fact_table()//阶乘表,这里仅打表到20{ fact[0] = 1; for(int i = 1; i <= 20; i++) fact[i] = i * fact[i-1];}ll Cantor_expansion(char *s){ ll res = 0; int len = strlen(s); for(int i = 0; s[i]; i++) { int rnk = 0; for(int j = i+1; s[j]; j++) if(s[i] > s[j]) rnk++; res += rnk * fact[len-i-1]; } return res;}void Cantor_inverse_expansion(ll n, int m){//n是在全排列中的名次,注意是从0开始计数的,若从1开始计数则要减去1。m是元素个数 vector<int> num; int arr[N], k = 0; for(int i = 1; i <= m; i++) num.push_back(i); for(int i = m; i >= 1; i--) { ll r = n % fact[i-1]; ll t = n / fact[i-1]; n = r; sort(num.begin(), num.end()); arr[k++] = num[t]; num.erase(num.begin() + t); } for(int i = 0; i < k; i++) printf("%d", arr[i]); printf("\n");}int main(){ fact_table(); while(~ scanf("%s", s)) { int len = strlen(s); ll res = Cantor_expansion(s);//求出此排列的名次 printf("%lld\n", res); Cantor_inverse_expansion(res, len);//根据排列的名次复原此排列 } return 0;}
阅读全文
0 0
- 康托展开模板
- 康托展开与逆康托展开(模板)
- 康托展开/逆康托展开
- 康托展开 & 康托逆展开
- 康托展开&逆康托展开
- 康托展开 康托逆展开
- 康托展开
- 康托展开
- 康托展开
- 康托展开
- 康托展开
- 康托展开
- 康托展开
- 康托展开公式
- 康托展开
- 康托展开
- 康托展开
- 康托展开
- IDEA 导入java web项目后的相关配置
- Log4j的使用方法
- size_type,size_t和ptrdiff_t
- Java抽象类与接口的区别
- 1、Mac如何剪切文件
- 康托展开模板
- 539. Minimum Time Difference
- XGBoost:参数解释
- linux编程之静态库和动态库
- 静态绑定 动态绑定 缺省参数
- Lua基础(4)--注释符
- 开发板linux连接wifi的方法(一)
- jQuery的属性与样式之元素的数据存储
- 局部Mock