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;
}

 

posted @ 2013-01-30 14:54  SF-_-  阅读(269)  评论(0编辑  收藏  举报