题目本身不难,简单分析一下,就可以得出递推公式,然后写代码。下面的是我刚开始写的代码:
#include <iostream> using namespace std; int main() { int i,n; long long s[101]; memset(s,0,sizeof(s)); s[0]=s[1]=1; for(n=2;n<=100;n++) { for(i=1;i<=n/2;i++) { s[n]+=s[i-1]*s[n-i]; } s[n]*=2; if(n%2) s[n]+=s[(n-1)/2]*s[(n-1)/2]; } while(cin>>n && n+1) cout<<s[n]<<endl; }
思路是对的,可是在n=36时会爆,long long都装不下。
网上搜了一下,有位大牛解释的很详细,http://hi.baidu.com/nash635/item/ef76bf13bb415b24f6625c1f,大家可以自己看看。
打表的代码(大牛写的,转载下):
#include <stdio.h> char list[100][100]={ "1", "2", "5", "14", "42", "132", "429", "1430", "4862", "16796", "58786", "208012", "742900", "2674440", "9694845", "35357670", "129644790", "477638700", "1767263190", "6564120420", "24466267020", "91482563640", "343059613650", "1289904147324", "4861946401452", "18367353072152", "69533550916004", "263747951750360", "1002242216651368", "3814986502092304", "14544636039226909", "55534064877048198", "212336130412243110", "812944042149730764", "3116285494907301262", "11959798385860453492", "45950804324621742364", "176733862787006701400", "680425371729975800390", "2622127042276492108820", "10113918591637898134020", "39044429911904443959240", "150853479205085351660700", "583300119592996693088040", "2257117854077248073253720", "8740328711533173390046320", "33868773757191046886429490", "131327898242169365477991900", "509552245179617138054608572", "1978261657756160653623774456", "7684785670514316385230816156", "29869166945772625950142417512", "116157871455782434250553845880", "451959718027953471447609509424", "1759414616608818870992479875972", "6852456927844873497549658464312", "26700952856774851904245220912664", "104088460289122304033498318812080", "405944995127576985730643443367112", "1583850964596120042686772779038896", "6182127958584855650487080847216336", "24139737743045626825711458546273312", "94295850558771979787935384946380125", "368479169875816659479009042713546950", "1440418573150919668872489894243865350", "5632681584560312734993915705849145100", "22033725021956517463358552614056949950", "86218923998960285726185640663701108500", "337485502510215975556783793455058624700", "1321422108420282270489942177190229544600", "5175569924646105559418940193995065716350", "20276890389709399862928998568254641025700", "79463489365077377841208237632349268884500", "311496878311103321137536291518809134027240", "1221395654430378811828760722007962130791020", "4790408930363303911328386208394864461024520", "18793142726809884575211361279087545193250040", "73745243611532458459690151854647329239335600", "289450081175264899454283846029490767264392230", "1136359577947336271931632877004667456667613940", "4462290049988320482463241297506133183499654740", "17526585015616776834735140517915655636396234280", "68854441132780194707888052034668647142985206100", "270557451039395118028642463289168566420671280440", "1063353702922273835973036658043476458723103404520", "4180080073556524734514695828170907458428751314320", "16435314834665426797069144960762886143367590394940", "64633260585762914370496637486146181462681535261000", "254224158304000796523953440778841647086547372026600", "1000134600800354781929399250536541864362461089950800", "3935312233584004685417853572763349509774031680023800", "15487357822491889407128326963778343232013931127835600", "60960876535340415751462563580829648891969728907438000", "239993345518077005168915776623476723006280827488229600", "944973797977428207852605870454939596837230758234904050", "3721443204405954385563870541379246659709506697378694300", "14657929356129575437016877846657032761712954950899755100", "57743358069601357782187700608042856334020731624756611000", "227508830794229349661819540395688853956041682601541047340", "896519947090131496687170070074100632420837521538745909320"}; int main(void) { int k; while (scanf("%ld",&k)==1 && k+1) printf("%s\n",list[k-1]); return 0; }
笔者试图自己写个类的,发现有指针就太容易报错了。。。真心受不了,写了下面的代码,AC了。
代码的可读性较差,见谅。思路和之前的long long是一样的,只是把数字改成字符串而已。
#include<iostream> using namespace std; char s3[10000]; char temp[10000]; 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][100]; 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+1) cout<<s[n]<<endl; }
额,笔者自己写了个类,也贴上去,测试过AC了:
#include <iostream> using namespace std; const int MAX_LEN=100; 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() { int i,n; bigNumber s[101]={1,1}; for(n=2;n<=100;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+1) cout<<s[n]<<endl; }