HDOJ 1131 Count the Trees 简单解题报告
这道题简单分析一下,发现考的还是catalan数和高精度乘法,和上一题做法是一样的,乘个阶乘就好了。
这是百度上对catalan的介绍~http://baike.baidu.com/view/1154333.htm
笔者的AC代码:可读性依旧很差,还是打算自己写个高精度类的,完成的话继续贴在上面。
另外,笔者的做题顺序是杭电上的ACM STEPS的顺序,初学者可以试试,题目是由易到难的,做做还是有好处的。
#include<iostream> using namespace std; char s3[10000]; char temp[10000]; char N[4]; void num(int one) { memset(N,0,sizeof(N)); if(one<10) N[0]=one+'0'; else if(one<100) { N[0]=one/10+'0'; N[1]=one%10+'0'; } else { N[0]='1'; N[2]=N[1]='0'; } } char* add(char* one, char* two) { char* s[2]; s[0]=one; s[1]=two; int a,b,lena,lenb,flag,i,temp; a=(strlen(s[1])>strlen(s[0])); b=1-a; lena=strlen(s[a]); lenb=strlen(s[b]); memset(s3,0,sizeof(s3)); flag=0; temp=0; for(i=0;i<lenb;i++) { temp=s[a][lena-1-i]-'0'+s[b][lenb-1-i]-'0'+flag; s3[i]=temp%10+'0'; flag=(temp>9); } for(;i<lena;i++) { temp=s[a][lena-1-i]-'0'+flag; s3[i]=temp%10+'0'; flag=(temp>9); } if(flag) { s3[lena++]='1'; s3[lena]='\0'; } for(i=0;i<lena/2;i++) { temp=s3[i]; s3[i]=s3[lena-1-i]; s3[lena-1-i]=temp; } return s3; } char* mul(char* one ,char* two) { int a,b,lena,lenb,lenc,i,j,temp; char* s[2]={one ,two}; int t[10000]; a=(strlen(s[1])>strlen(s[0])); b=1-a; lena=strlen(s[a]); lenb=strlen(s[b]); memset(t,0,sizeof(t)); for(i=0;i<lena;i++) for(j=0;j<lenb;j++) t[i+j]+=(s[a][lena-1-i]-'0')*(s[b][lenb-1-j]-'0'); lenc=lena+lenb-1; for(i=0;i<lenc;i++) { t[i+1]+=t[i]/10; t[i]%=10; } while(t[lenc]%10) { t[lenc+1]=t[lenc]/10; t[lenc]=t[lenc++]%10; } memset(s3,0,sizeof(s3)); for(i=0;i<lenc;i++) { s3[lenc-i-1]=t[i]+'0'; } return s3; } void copy(char* one=temp, char* two=s3) { for(int i=0;i<=strlen(two);i++) one[i]=two[i]; } int main() { int i,n; char s[101][1000]; char a[101][1000]; a[0][0]='1'; a[0][1]='\0'; for(i=1;i<101;i++) { a[i][0]='1'; a[i][1]='\0'; num(i); mul(a[i-1],N); copy(a[i]); } for(i=0;i<101;i++) { s[i][0]='0'; s[i][1]='\0'; } s[0][0]=s[1][0]='1'; for(n=2;n<=100;n++) { for(i=1;i<=n/2;i++) { mul(s[i-1],s[n-i]); copy(); add(temp,s[n]); copy(s[n]); } add(s[n],s[n]); copy(s[n]); if(n%2) { mul(s[(n-1)/2], s[(n-1)/2]); copy(); add(temp,s[n]); copy(s[n]); } } while(cin>>n && n) cout<<mul(s[n],a[n])<<endl; }
自己写了一个类,AC了,贴上去~
#include <iostream> using namespace std; const int MAX_LEN=1000; int temp[MAX_LEN]; class bigNumber { public: bigNumber() { memset(number,0,sizeof(number)); number[0]='0'; } bigNumber(char *str) { memcpy(number,str,strlen(str)+1); } bigNumber(int a) { int i=0; memset(number,0,sizeof(number)); if(a==0) number[0]='0'; else { while(a) { number[i++]=a%10+'0'; a/=10; } _strrev(number); } } ~bigNumber() { } char* getNumber() { return number; } friend ostream& operator<<(ostream& output, bigNumber& t) { output<<t.getNumber(); return output; } bigNumber& operator+(bigNumber& t) { bigNumber* a=strlen(this->getNumber())>strlen(t.getNumber())?this:&t; bigNumber* b=strlen(this->getNumber())>strlen(t.getNumber())?&t:this; bigNumber* c=new bigNumber(); char *x=a->getNumber(); char *y=b->getNumber(); char *z=c->getNumber(); int lenx=strlen(x); int leny=strlen(y); int i; int flag=0; for(i=0;i<leny;i++) { z[i]=(x[lenx-1-i]-'0')+(y[leny-1-i]-'0')+flag; flag=z[i]>9; z[i]=z[i]%10+'0'; } for(;i<lenx;i++) { z[i]=(x[lenx-1-i]-'0')+flag; flag=z[i]>9; z[i]=z[i]%10+'0'; } if(flag) z[i]='1'; _strrev(z); return *c; } bigNumber& operator*(bigNumber& t) { bigNumber* c=new bigNumber(); char *x=this->getNumber(); char *y=t.getNumber(); char *z=c->getNumber(); int lenx=strlen(x); int leny=strlen(y); int i,j; memset(temp,0,sizeof(temp)); for(i=0;i<lenx;i++) for(j=0;j<leny;j++) temp[i+j]+=(x[lenx-1-i]-'0')*(y[leny-1-j]-'0'); for(i=0;(i<lenx+leny-1) || temp[i]>9;i++) { if(temp[i]>9) temp[i+1]+=temp[i]/10; z[i]=temp[i]%10+'0'; } z[i]=temp[i]+'0'; while(z[i]=='0') z[i--]=0; _strrev(z); return *c; } bigNumber& operator=(bigNumber& t) { memcpy(number,t.getNumber(),strlen(t.getNumber())+1); return *this; } bigNumber& operator=(char *str) { memcpy(number,str,strlen(str)+1); return *this; } private: char number[MAX_LEN]; }; int main() { bigNumber t[101]={1,1}; bigNumber s[101]={1,1}; int i,n; for(n=2;n<=100;n++) { t[n]=t[n-1]*bigNumber(n); for(i=1;i<=n/2;i++) s[n]=s[n]+s[i-1]*s[n-i]; s[n]=s[n]*bigNumber(2); if(n%2) s[n]=s[n]+s[(n-1)/2]*s[(n-1)/2]; } while(cin>>n && n) cout<<s[n]*t[n]<<endl; }