NYOJ 139 我排第几个(康托展开)
2015-10-11 09:25
344 查看
根据康托展开,对于每一个字符,假设它后面有k个字符比它小,则当前序列的排序会增大k*f[12-i],其中f[i]是是i的阶乘。
该题就是康托展开的裸题, 利用康托展开,我们不仅可以快速的求某个排列是第几个排列,而且可以快速求出第几个排列是什么。 方法就是此题的逆。
关于康托展开,大家可以看这里:点击打开链接
细节参见代码:
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
int main() {
long long f[15];
f[1]=1;
for(int i=2;i<=12;i++) {
f[i]=f[i-1]*i;
}
char s[15]; int t;
while(~scanf("%s",s+1)) {
long long sum=0;
for(int i=1;i<=12;i++) {
int k=0;
for(int j=i+1;j<=12;j++) {
if(s[i] > s[j]) k++;
}
sum+=f[12-i]*k;
}
printf("%I64d\n",sum+1);
}
return 0;
}
该题就是康托展开的裸题, 利用康托展开,我们不仅可以快速的求某个排列是第几个排列,而且可以快速求出第几个排列是什么。 方法就是此题的逆。
关于康托展开,大家可以看这里:点击打开链接
细节参见代码:
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
int main() {
long long f[15];
f[1]=1;
for(int i=2;i<=12;i++) {
f[i]=f[i-1]*i;
}
char s[15]; int t;
while(~scanf("%s",s+1)) {
long long sum=0;
for(int i=1;i<=12;i++) {
int k=0;
for(int j=i+1;j<=12;j++) {
if(s[i] > s[j]) k++;
}
sum+=f[12-i]*k;
}
printf("%I64d\n",sum+1);
}
return 0;
}
相关文章推荐
- 1.m分解阶乘之和
- 2.几种递推数
- 3.欧拉函数
- 4.快速幂模m算法
- 5.扩展欧几里得&&中国剩余定理
- 6.数论_web
- 编程之美2015初赛A
- 数论题集
- hdu 4738 Caocao's Bridges 2013 ACM-ICPC杭州赛区网络赛 1001 双连通分量
- hdu 4750 2013 ACM/ICPC Asia Regional Nanjing Online 1003 并查集+离线操作
- hust 1626 Cutting rope
- HDU5117
- 1216: 斐波那契数列
- 1217: 打印沙漏
- 我的ACM-ICPC资源整理
- 阶与原根学习笔记
- HDU 1299 Diophantus of Alexandria
- Leftmost Digit(HDU 1060)
- Rightmost Digit(HDU 1061)
- ZOJ 2674 Strange Limit 欧拉定理