题意:给出一堆字母 问这些字母组成的字符串中第k大的
排列组合,具体看代码
//寒假集训被何柱大大踩好惨(>_<)
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<stack> 11 #include<string> 12 13 using namespace std; 14 int n; 15 char s[20]; 16 char ans[20];int cnt[26];int f[17]; 17 18 int main(){ 19 f[0]=1; 20 for (int i=1;i<=16;i++) f[i]=f[i-1]*i; 21 while (1){ 22 scanf("%s%lld",s,&n); 23 if (n==0 && s[0]=='#') return 0; 24 int len=strlen(s); 25 memset(cnt,0,sizeof(cnt)); 26 for (int i=0;i<len;i++){ 27 cnt[s[i]-'A']++; 28 } 29 for (int i=0;i<len;i++){ 30 int now=0; 31 int tmp=0; 32 for (int j=0;j<26;j++){//计算当前位 即把第i个字母放在首位时能产生多少种组合 33 if (cnt[j]!=0){ 34 tmp=f[len-i-1]; 35 for (int k=0;k<26;k++){ 36 if (j==k) 37 tmp=tmp/f[cnt[k]-1];//去除重复的排列 如果已经有一个放在了当前位 cnt要-1 38 else 39 tmp=tmp/f[cnt[k]]; 40 } 41 if (now+tmp>=n){//如果超出 就把第j个放在当前位 退出 42 cnt[j]-=1; 43 n-=now; 44 ans[i]=j+'A'; 45 break; 46 } 47 now=now+tmp;//累加 48 } 49 } 50 } 51 for (int i=0;i<len;i++) printf("%c",ans[i]); 52 printf(" "); 53 } 54 return 0; 55 } 56 /* 57 ACM 5 58 ICPC 12 59 REGION 274 60 # 0 61 */