lightoj 1060 - nth Permutation 组合数学
来源:互联网 发布:car软件 编辑:程序博客网 时间:2024/06/06 09:22
给定一个字符串和k,求字符串第k大字典序的排列...
康拓逆展开...可以求没有重复元素的第k个排列,有重复的话,方法是一样的,只是求解方案数变了。
由单纯的阶乘变为len!/cnt[i]!(0<=i<26),cnt[i]为第i个字母出现的次数。
而且某一位要放置的字母出现多次,那么只需要计算一次就好,因为所有的排列都是一模一样的。
#include<bits/stdc++.h>using namespace std;#define inf 0x7fffffff#define ll long longchar s[22];int a[28];ll f[23];int main(){ int t; f[0]=1; for(int i=1;i<=22;i++) f[i]=f[i-1]*i; scanf("%d",&t); for(int cas=1;cas<=t;cas++) { int n; scanf("%s %d",s,&n); int len=strlen(s); memset(a,0,sizeof(a)); for(int i=0;i<len;i++) { a[s[i]-'a']++; } ll zs=f[len]; for(int i=0;i<26;i++) zs/=f[a[i]]; printf("Case %d: ",cas); if(zs<n) { puts("Impossible"); continue; } for(int i=0;i<len;i++)//当前第i位选择那个字母 { for(int j=0;j<26;j++)//第i个字母为j { if(a[j]==0) continue; a[j]--;//假如第j个字母做在第i个位置的总排列情况为tmp种 ll tmp=f[len-i-1]; for(int k=0;k<26;k++) tmp/=f[a[k]]; if(n<=tmp)//如果方案数已经超过n,那么肯定这一位字母是第j个 { printf("%c",'a'+j); break; } n-=tmp;//否则肯定是下一个字母的排列 a[j]++; } } printf("\n"); } return 0;}
0 0
- lightoj 1060 - nth Permutation 组合数学
- LightOJ 1060nth Permutation(组合数--k大字典序)
- LightOJ - 1060 nth Permutation(计数)
- LightOJ 1060 - nth Permutation(dp)
- LightOJ-1060-dfs,组合数学
- LightOJ 1060 - nth Permutation (逆康托展开的思想)
- lightoj 1060 - nth Permutation(逆康拓展开)
- LIGHTOJ 1005(组合数学)
- lightoj 1005 - Rooks 【组合数学】
- lightoj 1005 - Rooks 【组合数学】
- Lightoj 1058 (组合数学)
- LightOJ-1005-Rooks [组合数学]
- UVA 11027 Palindromic Permutation(组合数学)
- HDU 5753 Permutation Bo (组合数学)
- LightOJ 1005 - Rooks (dp、组合数学)
- lightoj 1095 - Arrange the Numbers 组合数学
- 【LightOJ】1104 - Birthday Paradox(组合数学)
- lightoj 1005 - Rooks(组合数学)
- 静态库的使用方法
- 欢迎使用CSDN-markdown编辑器
- MySQL中group_concat函数
- 使用VS2008自带的dumpbin.exe查看dll包含的函数
- spring DataSourceUtils
- lightoj 1060 - nth Permutation 组合数学
- leetcode-24 Swap Nodes in Pairs
- spring 事物日志
- leetcode 每日一题 102. Binary Tree Level Order Traversal
- Spring单实例、多线程安全、事务解析
- PHP7 扩展之自动化测试
- spring 事物 线程池 测试
- Android 如何找到最匹配资源
- 图片处理 javax.imageio.IIOException: Unsupported Image Type