【BZOJ 2822】树屋阶梯

Description

暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题。由于地上露营湿气重,必须选择在高处的树屋露营。小龙分配的树屋建立在一颗高度为N+1尺(N为正整数)的大树上,正当他发愁怎么爬上去的时候,发现旁边堆满了一些空心四方钢材(如图1.1),经过观察和测量,这些钢材截面的宽和高大小不一,但都是1尺的整数倍,教官命令队员们每人选取N个空心钢材来搭建一个总高度为N尺的阶梯来进入树屋,该阶梯每一步台阶的高度为1尺,宽度也为1尺。如果这些钢材有各种尺寸,且每种尺寸数量充足,那么小龙可以有多少种搭建方法?(注:为了避免夜里踏空,钢材空心的一面绝对不可以向上。)

 

   以树屋高度为4尺、阶梯高度N=3尺为例,小龙一共有如图1.2所示的5种

   搭 建方法:

   

 

Input

一个正整数 N(1N500),表示阶梯的高度

Output

一个正整数,表示搭建方法的个数。(注:搭建方法个数可能很大。)

Sample Input

3

Sample Output

5

HINT

1  ≤N500

 

分析:

  卡特兰数,公式为H(n) = C(2n,n)/(n+1)。

  开个高精度500就可以过了。

  N<=50000的做法:分解成质数,把质数乘起来。

 

代码:

 1 #include <cstdio>
 2 
 3 struct BigNumber
 4 {
 5     int N[100000], t[100000], s;
 6 
 7     void Set (int x)
 8     {
 9         N[0] = x;
10         s = 1;
11         while (N[s - 1] > 9)
12         {
13             N[s] = N[s - 1] / 10;
14             N[s - 1] %= 10;
15             s++;
16         }
17     }
18 
19     void times (const int x)
20     {
21         for (int i = 0; i < s; i++)
22             t[i] = N[i], N[i] = 0;
23         for (int i = 0; i < s; i++)
24         {
25             if (N[i] > 9)
26             {
27                 N[i + 1] += N[i] / 10;
28                 N[i] %= 10;
29             }
30             N[i] += t[i] * x;
31             if (N[i] > 9)
32             {
33                 N[i + 1] += N[i] / 10;
34                 N[i] %= 10;
35             }
36         }
37         while (N[s] > 0)
38         {
39             if (N[s] > 9)
40             {
41                 N[s + 1] += N[s] / 10;
42                 N[s] %= 10;
43             }
44             s++;
45         }
46     }
47 
48     void Print ()
49     {
50         for (int i = s - 1; i >= 0; i--)
51             printf("%d", N[i]);
52         printf ("\n");
53     }
54 } bn;
55 
56 int n, n2, m, cnt, f[110000], k[110000];
57 
58 int main ()
59 {
60     scanf ("%d", &n);
61     n2 = n * 2;
62     f[0] = f[1] = 1;
63     for (int i = 2; i <= n2; i++)
64     {
65         if (!f[i])
66         {
67             for (int j = i; j <= n2; j += i)
68             {
69                 f[j] = 1;
70                 cnt = 0, m = j;
71                 while (m % i == 0)
72                     cnt++, m /= i;
73                 if (j <= n) k[i] -= cnt;
74                 else if (j > n + 1) k[i] += cnt;
75             }
76         }
77     }
78     bn.Set (1);
79     for (int i = 0; i <= n2; i++)
80         for (int j = 0; j < k[i]; j++)
81             bn.times (i);
82     bn.Print ();
83 }

 

posted @ 2015-04-09 20:22  Lightning34  阅读(163)  评论(0编辑  收藏  举报