vijos - P1092全排列 (康托展开 + 康托展开的逆运算)
2015-08-21 23:23
405 查看
P1092全排列
Accepted
标签:[显示标签]
输入两个自然数m,n 1<=n<=20,1<=m<=n!
输出n个数的第m种全排列。
如 :
输入 3 1
输出 1 2 3
每两个数之间空1格
样例输入1[复制]
样例输出1[复制]
各个测试点1s
lk
给予一个目标排列,求解他的全排列过程中的第几个排列是通过康托展开:
找出45231在这个排列中的顺序
比4小的数有3个
比5小的数有4个但4已经在之前出现过了所以是3个
比2小的数有1个
比3小的数有两个但2已经在之前出现过了所以是1个
比1小的数有0个
那么45231在这个排列中的顺序是3*4!+3*3!+1*2!+1*1!+0*0!+1=94
如此,可以发现,所谓的第几个则是少于某个数的个数乘以阶乘。
给予一个原序列,以及一个数n代表着目标排列是全排列中的第几个排列,是通过康托展开的逆运算:
一个数量为5的排列,现在要你找出第96种排序序列是什么
首先用96-1得到95(将他本身这一个种给删掉,可以直接判断)
用95去除4! 得到3余23
用23去除3! 得到3余5
用5去除2!得到2余1
用1去除1!得到1余0
有3个数比它小的数是4
所以第一位是4
有3个数比它小的数是4但4已经在之前出现过了所以是5(因为4在之前出现过了所以实际比5小的数是3个)
有2个数比它小的数是3
有1个数比它小的数是2
最后一个数只能是1
所以这个数是45321
具体情况,请查看代码
Accepted
标签:[显示标签]
描述
输入两个自然数m,n 1<=n<=20,1<=m<=n!输出n个数的第m种全排列。
如 :
输入 3 1
输出 1 2 3
格式
输入格式
在一行中输入n m输出格式
一个数列,既n个数的第m种排列每两个数之间空1格
样例1
样例输入1[复制]
3 2
样例输出1[复制]
1 3 2
限制
各个测试点1s
来源
lk给予一个目标排列,求解他的全排列过程中的第几个排列是通过康托展开:
找出45231在这个排列中的顺序
比4小的数有3个
比5小的数有4个但4已经在之前出现过了所以是3个
比2小的数有1个
比3小的数有两个但2已经在之前出现过了所以是1个
比1小的数有0个
那么45231在这个排列中的顺序是3*4!+3*3!+1*2!+1*1!+0*0!+1=94
如此,可以发现,所谓的第几个则是少于某个数的个数乘以阶乘。
给予一个原序列,以及一个数n代表着目标排列是全排列中的第几个排列,是通过康托展开的逆运算:
一个数量为5的排列,现在要你找出第96种排序序列是什么
首先用96-1得到95(将他本身这一个种给删掉,可以直接判断)
用95去除4! 得到3余23
用23去除3! 得到3余5
用5去除2!得到2余1
用1去除1!得到1余0
有3个数比它小的数是4
所以第一位是4
有3个数比它小的数是4但4已经在之前出现过了所以是5(因为4在之前出现过了所以实际比5小的数是3个)
有2个数比它小的数是3
有1个数比它小的数是2
最后一个数只能是1
所以这个数是45321
具体情况,请查看代码
#include <map> #include <set> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <iostream> #include <string> #include <sstream> #include <cstdlib> #include <ctime> #include <cctype> using namespace std; #define pb push_back #define mp make_pair #define fillchar(a, x) memset(a, x, sizeof(a)) #define copy(a, b) memcpy(a, b, sizeof(a)) #define S_queue<P> priority_queue<P, vector<P>,greater<P> > typedef long long LL; typedef pair<int, int > PII; typedef unsigned long long uLL; template<typename T> void print(T* p, T* q, string Gap = " "){int d = p < q ? 1 : -1;while(p != q){cout << *p;p += d;if(p != q) cout << Gap; }cout << endl;} template<typename T> void print(const T &a, string bes = "") {int len = bes.length();if(len >= 2)cout << bes[0] << a << bes[1] << endl;else cout << a << endl;} const int INF = 0x3f3f3f3f; const int MAXM = 1e5; const int MAXN = 1e4; uLL F[21]={1,1,2,6,24,120,720,5040,40320, 362880,3628800,39916800, 479001600,6227020800,87178291200, 1307674368000,20922789888000,355687428096000, 6402373705728000,121645100408832000,2432902008176640000}; bool vis[30]; uLL Fig[25]; int main(){ uLL n, m, cnt; cin >> n >> m; m --; for(uLL i = n - 1;i > 0;i --){ uLL k = m / F[i]; m %= F[i]; cnt = k + 1; uLL xs = 1,ft = 0; while(xs <= cnt){ ft ++; if(!vis[ft]) xs ++; } vis[ft] = true; cout << ft << " "; } for(int i = 1;i <= n;i ++){ if(!vis[i]) cout << i; } cout << endl; return 0; }
相关文章推荐
- A Round Peg in a Ground Hole - POJ 1584
- 【springmvc】java web使用ajaxSubmit方法实现Excel文件上传
- Redis(7)Creating and Using Cluster Mode
- iOS程序员面试要注意的几个问题
- vs2012快捷键失效解决办法
- 和为定值的两个数
- hdu 3874 Necklace(离线操作+树状数组或线段树)
- 2015/08/21
- lncRNA研究
- F#相关图书推荐
- iOS开发所需英语词汇整理
- 2015-8-1(1)
- 模拟 nbut1225 NEW RDSP MODE I
- sqlite3 journal
- SPOJ 3267 DQUERY(主席树在线|树状数组离线)
- 鸟哥的Linux私房菜-----16、程序与资源管理
- 论软件设计中的哲学观
- 微信分享SDK导入报错 Undefined symbols for architecture i386:
- UISlider的使用
- Scala学习笔记--for,function,lazy用法小结