HDOJ 1134 Game of Connections 简单解题报告

    题目本身不难,简单分析一下,就可以得出递推公式,然后写代码。下面的是我刚开始写的代码:

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

 

posted @ 2013-01-29 16:42  SF-_-  阅读(610)  评论(0编辑  收藏  举报