题目

Description
  对于n个元素的排列P=(p1,p2,……,pn),请你编写一个程序,在不构造出所有排列的情况下,直接输出该排列在按字典序排列的字典中的序数d§,其中p1∈{1,2,3,…,n},1<=n<=50。例如:n=4,若p=(2,3,4,1),则d§=10;若p=(4,2,1,3),则d§=21

Input
  每一行对应一个数据,格式为(n,(p1,p2,….,pn))其中n表示排列的元素个数,(p1,p2,…pn)就是这n个元素的某个排列。文件的最后一行只包含“-1”,表示输入文件结束。

Output
  对于每个数据,输出对应的d§。所有数据的结果都输出到一行中,用逗号分开。


解题思路

虽然今天的题目都很简单,有两位同学改做B组题。但我是真的找不到规律,于是什么都没有敲。正解是康托展开:
X = a [ n ] ( n − 1 ) ! + a [ n − 1 ] ( n − 2 ) ! + . . . + a [ 2 ] ∗ 1 ! + a [ 1 ] ∗ 0 ! X=a[n](n-1)!+a[n-1](n-2)!+...+a[2]*1!+a[1]*0! X=a[n](n−1)!+a[n−1](n−2)!+...+a[2]∗1!+a[1]∗0!
[ 其 中 a [ i ] 为 当 前 未 出 现 的 元 素 中 是 排 在 第 几 个 ( 从 0 开 始 ) , 并 且 0 &lt; = a [ i ] &lt; i ( 1 &lt; = i &lt; = n ) ] [其中a[i]为当前未出现的元素中是排在第几个(从0开始),并且0&lt;=a[i]&lt;i(1&lt;=i&lt;=n) ] [其中a[i]为当前未出现的元素中是排在第几个(从0开始),并且0<=a[i]<i(1<=i<=n)]

因为数据较大,还要外加两个高精乘单精


代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
int n,a[81],b[55][150],ans[150]; bool l;
void dff(int k)
{for (int i=1;i<=145;i++){b[k][i]=b[k][i]+b[k-1][i]*k; b[k][i+1]=b[k][i+1]+b[k][i]/10; b[k][i]=b[k][i]%10; }
}
void df(int z,int k)
{for (int i=1;i<=145;i++){ans[i]=ans[i]+b[k][i]*z; ans[i+1]=ans[i+1]+ans[i]/10; ans[i]=ans[i]%10; }
}
int main()
{b[0][1]=1; string s; for (int i=1;i<=50;i++) dff(i); while (1){cin>>s; int e=0,t=-1; bool bb=0; for (int i=0;i<s.size();i++){if (s[i]=='-') return 0; if (s[i]>='0'&&s[i]<='9') { bb=1; e=e*10+s[i]-'0'; }else if (bb==1) { a[++t]=e; e=0; bb=0;}}n=a[0]; a[0]=0; memset(ans,0,sizeof(ans)); ans[1]=1; if (l==1) printf(","); if (n!=-1) l=1;for (int i=1;i<n;i++)   {int g=0; for (int j=1;j<i;j++)if (a[j]<a[i]) g++; df(a[i]-1-g,n-i);}int q=145; while (q>1&&ans[q]==0) q--; for (int i=q;i>=1;i--)printf("%d",ans[i]); }
}

【GDOI2003】排列的编码 {康托展开+高精度}相关推荐

  1. LeetCode 60. 第k个排列(回溯 康托展开)

    文章目录 1. 题目 2. 解题 2.1 回溯 2.2 数学-康托展开 1. 题目 给出集合 [1,2,3,-,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = ...

  2. nssl1156-今天你AK了吗?【康托展开,高精度,二分答案,树状数组】

    正题 题目大意 求n个数的全排列的第k个. 解题思路 首先康拓逆展开 ∑ii<=nxi(n−i)!\sum^{i<=n}_i x_i(n-i)!∑ii<=n​xi​(n−i)! 求每 ...

  3. 组合数学 —— 康托展开

    [概述] 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩,在组合数学中,其解决的是当前排列在全排列中的名次问题. 简单来说,给定一个 n 位数的全排列,可根据康托展开公式确定其应 ...

  4. 关于康托展开的用途及写法

    在处理八数码这一类需要用到全排列的问题的时候, 存储往往是一个难题, 因为明明只有n!种情况, 数字的长度却有n, 用数组是肯定不行的. 这个时候, 康托展开就派上了用场, 当然, 在条件允许的情况下 ...

  5. 康托展开和逆康托展开

    简述 康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩.设有n个数(1,2,3,4,-,n),可以有组成不同(n!种)的排列组合,康托展开表示的就是是当前排列组合在n个不同元素 ...

  6. 洛谷P1088.火星人【模拟/搜索/康托展开】

    洛谷P1088.火星人[模拟/搜索/康托展开] 题干 题目描述 输入格式 输出格式 输入输出样例 说明/提示 题意 思路一--模拟 分析 上代码 思路二--搜索 分析 上代码 思路三--变进制数与康托 ...

  7. (康托展开解释)+ NYOJ 139 我排第几个

    描述 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? 输入 第一行有一个整数n(0<n& ...

  8. 康托展开(Cantor expansion)

    康托展开是一个全排列到一个自然数的双射.所以可逆. 康托展开:给定一个数n,和一个n位的全排列,求出这个排列是第几位X 逆康托展开:给定一个数n,和这个排列占第几位X, 求出这个排列 这里X(注意第一 ...

  9. 【BZOJ】3301: [USACO2011 Feb] Cow Line(康托展开)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3301 其实这一题很早就a过了,但是那时候看题解写完也是似懂非懂的.... 听zyf神犇说是康托展开, ...

最新文章

  1. vs debug 模式生成的exe 另一台电脑_C++利用spdlog生成日志
  2. Linux线程(四)
  3. 面向对象中构造函数的小练习
  4. ajax jsp模糊查询源码,Ajax动态执行模糊查询功能
  5. docker探索-docker安装运行tomcat(六)
  6. UML建模系列文章总结 [转]
  7. The Distribution File System
  8. 【idea基础知识】project structure中没有web 或没有spring
  9. Android中URI的格式
  10. python爬虫requests库_python爬虫基础教程:requests库(二)代码实例
  11. 文档转换html6,html学习文档-6、HTML 文本格式化(示例代码)
  12. Pyhton-Web框架之【Django】
  13. 1059: [ZJOI2007]矩阵游戏 - BZOJ
  14. 拓端tecdat|R语言使用最优聚类簇数k-medoids聚类进行客户细分
  15. 数据迁移其实是很难的
  16. 《机器学习实战》中英文电子书 + 源代码下载
  17. 基于HLW8032芯片的电能参数采集--附测试软件
  18. pymilvus基操
  19. 机器视觉运动控制一体机应用例程|锂电池组装线上的读码应用
  20. linux状态栏显示命令,Ubuntu状态栏显示网速CPU

热门文章

  1. Spring MVC上传图片,Java二…
  2. 使用servlet提供接口
  3. 去哪儿网2014笔试算法题汇总
  4. usb3.0 ssd 测试软件,对比评测告诉你USB3.0+SSD能否干掉HDD
  5. 什么是OID(全局对象标识符)
  6. 21天战拖记——Day21:《小强升职记》学习感受(2014-05-24)
  7. 【XLA】一、【构图阶段】图优化器的注册和执行
  8. 18650锂电池镍带镀镍钢片(连接带)怎么拆,怎么容易焊锡
  9. 佳能镜头EOS系统EF协议逆向工程(一)
  10. 非正式的沟通往往比正式的沟通更有效,更重要