我的思路是采用递归的方法。总体思路是,先确定第K个串的第一个字符是0还是1,然后再递归确定第二个字符是0还是1,直到剩下字符全为0或者全为1.
具体来说是这样的:
1、先假设N个0和M个1的组合数为total,其中total=(N+M)!/[N!*M!],则N-1个0和M个1的组合数为[N/(N+M)]*total,设为y,对应的N个0和M-1个1的组合数为[M/(N+M)]*total.
2、当K>total时,输出Impossible,结束返回;
3、当N=0时,K又是合法的,则K只能为1,则输出M个1;对应的,当M=0时,K又是合法的,则K只能为1,则输出N个0;
4、当K<=y时,说明第K个串的第一个字符为0,则输出0,然后再递归求解N-1个0,M个1,求第K个串的情况;否则,说明第K个串的第一个字符为1,则输出1,然后再递归求解N个0,M-1个1,求第K-y个串的情况。
具体代码如下:
1 #include<stdio.h>
2 /**
3 * 求n的阶乘
4 */
5 int factorial(int n)
6 {
7 if(n == 0)
8 return 0;
9 int i = 1;
10 int result = 1;
11 while(i<=n)
12 {
13 result = result*i;
14 i++;
15 }
16 return result;
17 }
18 /*
19 * n个0 m个1的组合数
20 */
21 int combination(int n,int m)
22 {
23 if(n==0 && m==0)
24 return 0;
25 if(n==0 || m==0)
26 return 1;
27 return factorial(n+m)/(factorial(n)*factorial(m));
28 }
29 /**
30 * 采用递归的方法找到第K个串
31 */
32 int theKString(int N,int M, int K, int total)
33 {
34 int y,z;
35 if(K>total)
36 {
37 printf("Impossible
");
38 return 0;
39 }
40 if(N==0)
41 {
42 while(M-->0)
43 printf("1");
44 return 1;
45 }else if(M ==0)
46 {
47 while(N-->0)
48 printf("0");
49 return 1;
50 }
51 y = total*N/(N+M);
52 z = total*M/(N+M);
53
54 if(K<=y)
55 {
56 printf("0");
57 return theKString(N-1,M,K,y);
58 }else
59 {
60 printf("1");
61 return theKString(N,M-1,K-y,z);
62 }
63
64 }
65
66 int main(void)
67 {
68 int num;
69 int N,M,K;
70 scanf("%d",&num);
71 while(num-->0)
72 {
73 scanf("%d %d %d",&N,&M,&K);
74 theKString(N,M,K,combination(N,M));
75 printf("
");
76 }
77 return 0;
78 }
声明,代码只能确保题目给的三个case的输出是正确的,没有online Judege。