Light OJ 1060 - nth Permutation(组合数)

题目大意:

给你一个字符串,问这个字符串按照特定顺序排列之后,第n个字符串是哪个?

题目分析:

首先我们要会求解总个数。也就是共有len个字符,每个字符有ki个,那么总组合方式是多少种?

总组合方式就是: (len!)/(ki !), 把每个ki的阶乘都除一边,最后算出的结果就是答案了。

那么问题就剩下解决第n个字符串的的问题了。

下面我们先了解一下排序计数:

排序计数

  • 如1,2,3,4的全排列,共有4!种,求第10个的排列是(从1计起)?
  • 先试首位是1,后234有3!=6种<10,说明首位1偏小,问题转换成求2开头的第(10-6=4)个排列,而3!=6 >= 4,说明首位恰是2。
  • 第二位先试1(1没用过),后面2!=2个<4,1偏小,换成3(2用过了)为第二位,待求序号也再减去2!,剩下2了。而此时2!>=2,说明第二位恰好是3。
  • 第三位先试1,但后面1!<2,因此改用4。末位则是1了。
  • 这样得出,第10个排列是2-3-4-1。

然后求解方法和上面阶乘的方法大同小异。

=============================================================================================================

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<vector>
 8 #include<map>
 9 using namespace std;
10 typedef long long LL;
11 const int INF = 1e9+7;
12 const int MAXN = 555;
13 int vis[30];
14 char str[50];
15 LL Fact[25], n;
16 
17 void DFS(int pos,LL num)
18 {
19     if(pos == 0)
20     {
21         printf("\n");
22         return ;
23     }
24 
25     for(int i=0; i<26; i++)
26     {
27         if(vis[i] == 0) continue;
28 
29         LL temp = Fact[pos-1]*vis[i];
30 
31         for(int j=0; j<26; j++)
32             temp /= Fact[vis[j]];
33         if(num > temp)
34             num -= temp;
35         else
36         {
37             vis[i] --;
38             printf("%c", 'a'+i);
39             break;
40         }
41 
42     }
43     DFS(pos-1, num);
44 }
45 
46 
47 int main()
48 {
49     int T, cas = 1;
50     Fact[0] = 1;
51     for(int i=1; i<=22; i++)
52     Fact[i] = Fact[i-1] * i;
53     scanf("%d", &T);
54 
55     while(T --)
56     {
57         scanf("%s %lld",str, &n);
58 
59         memset(vis, 0, sizeof(vis));
60         int len = strlen(str);
61         for(int i=0; str[i]; i++)
62             vis[str[i] - 'a'] ++;
63         LL ans = Fact[len];
64 
65         printf("Case %d: ", cas ++);
66         for(int i=0; i<26; i++)
67             ans /= Fact[vis[i]];
68 
69         if(ans < n)
70             puts("Impossible");
71         else
72             DFS(len, n);
73     }
74     return 0;
75 }

 

posted @ 2015-10-29 14:48  向前走丶不回首  阅读(269)  评论(0编辑  收藏  举报