nyoj164 Game of Connections(Catalan数、大数乘法) 模板

 

Game of Connections

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
 
描述
This is a small but ancient game. You are supposed to write down the numbers 1, 2, 3, . . . , 2n - 1, 2n consecutively in clockwise order on the ground to form a circle, and then, to draw some straight line segments to connect them into number pairs. Every number must be connected to exactly one another. 
And, no two segments are allowed to intersect. 
It's still a simple game, isn't it? But after you've written down the 2n numbers, can you tell me in how many different ways can you connect the numbers into pairs? Life is harder, right?
 
输入
Each line of the input file will be a single positive number n, except the last line, which is a number -1.
You may assume that 1 <= n <= 100.
输出
For each n, print in a single line the number of ways to connect the 2n numbers into pairs
样例输入
2
3
-1
样例输出
2
5
算法分析:Catalan数、大数加法、大数乘法,在大数运算中我采用string类型,可以返回值
View Code
  1 #include<iostream>
2 #include<cstring>
3 #include<string>
4 #include<cstdio>
5 using namespace std;
6
7 string add(string a,string b)//大数加法
8 {
9 int i,j,k,flag;
10 string c;
11 c="";
12 i=a.size()-1;j=b.size()-1;
13 k=0;flag=0;//flag为标记是否要进位
14 while(i>=0&&j>=0)
15 {
16 c+=(a[i]+b[j]-'0'+flag);
17 //往string类型的字符串加数字子不能像数组那样直接c[k++],会内存错误
18 flag=0;
19 if(c[k]>'9')
20 {
21 flag=1;
22 c[k]=c[k]-10;
23 }
24 i--;j--;k++;
25 }
26 while(i>=0)
27 {
28 c+=(a[i]+flag);
29 flag=0;
30 if(c[k]>'9')
31 {
32 flag=1;
33 c[k]=c[k]-10;
34 }
35 i--;k++;
36 }
37 while(j>=0)
38 {
39 c+=b[j]+flag;
40 flag=0;
41 if(c[k]>'9')
42 {
43 flag=1;
44 c[k]=c[k]-10;
45 }
46 j--;k++;
47 }
48 char t;
49 if(flag)
50 {
51 c+=(flag+'0');k++;
52 }
53 for(i=0,j=k-1;i<j;i++,j--)
54 {
55 t=c[i];c[i]=c[j];c[j]=t;
56 }
57 return c;
58 }
59
60 string mult(string a,string b)//大数乘法
61 {
62 int flag=0,i,j,k,p,q,t,max;
63 char ch;
64 string c,ans;
65 p=a.size()-1;q=b.size()-1;
66 ans="0";
67 for(i=p;i>=0;i--)//可以分解为p个一位数和一个大数的乘法
68 {
69 flag=0;c="";
70 for(j=i;j<p;j++) c+='0';
71 for(j=q;j>=0;j--)
72 {
73 t=(b[j]-'0')*(a[i]-'0')+flag;
74 flag=t/10;
75 c+=(t%10+'0');
76 }
77 if(flag) c+=(flag+'0');
78 for(j=0,k=c.size()-1;j<k;j++,k--)
79 {
80 ch=c[j];c[j]=c[k];c[k]=ch;
81 }
82 ans=add(ans,c);
83 }
84 return ans;
85 }
86
87 int main()
88 {
89 int i,j,n;
90 string a,ans[101];
91 ans[0]="1";ans[1]="1";ans[2]="2";ans[3]="5";
92 for(i=4;i<101;i++)ans[i]="0";
93 for(i=4;i<101;i++)
94 {
95 for(j=0;j<i;j++)
96 {
97 a=mult(ans[j],ans[i-j-1]);
98 ans[i]=add(ans[i],a);
99 }
100 }
101 while(cin>>n&&n!=-1)
102 {
103 cout<<ans[n]<<endl;
104 }
105 return 0;
106 }
 
 
大数乘法:大数*(一个 int64 范围之内的数) 可以用分段乘法
以下是 n! (n<=10000) 的代码
View Code
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N 10000
 5 
 6 using namespace std;
 7 
 8 int a[N];
 9 
10 int main()
11 {
12     int n,t,i,j,k;
13     while(cin>>n)
14     {
15         memset(a,0,sizeof(a));
16         a[0]=1;k=0;
17         for(i=2;i<=n;i++)
18         {
19             t=0;
20             for(j=0;j<=k;j++)
21             {
22                 a[j]=a[j]*i+t;
23                 t=a[j]/100000;
24                 a[j]=a[j]%100000;
25             }
26             if(t>0)
27             {
28                 k++;a[k]=t;
29             }
30         }
31         printf("%d",a[k]);
32         for(i=k-1;i>=0;i--)
33         {
34             printf("%05d",a[i]);
35         }
36         printf("\n");
37     }
38 }

 

 
posted @ 2012-03-30 16:40  mtry  阅读(1408)  评论(0编辑  收藏  举报