1. 程式人生 > >樓天城之做男人就過八道題(第一題…

樓天城之做男人就過八道題(第一題…

關於樓教主的第一題,感覺最費時間的還是高精度的實現。實現一萬位以上整數基本運算的萬進位制高精度模版就寫了快一天(題目裡用到大概也有幾百位吧),只能說太容易出錯了,得不斷地除錯修改。題目源地址是北大poj1737題,題目本身的組合數學的演算法是參考某位大牛的文章,在此附上地址http://hi.baidu.com/accplaystation/item/0b3b4e1654a07548e75e06f9 
下面分別是49和50個點時的結果以及原始碼,供參考:
49:
10263013515700550779116289728670421776807355856352253452035361907379108631238572 44548313982876228994987864700400759811456244128889754306386459557887432298148719 59173497103061147469088590424739631395981885494059279529144993759879407051757016 75516079509792662379977972835636452421052447375208813714109600679021766298295142 56225641238164014573644333472284672 50: 57775629806264131981532128463353986108213291999872288565750767218860631769630192 41340682335187078778417692523562748348836783209222917852889522593249600859338855 72481476441044041666245632947630667669900623389069655523344952222114179660086674 25130052344927925607827177068266427605834927592260049347147617842015437801204857 1333436567365397136152469165480980158369042006016  
#include "iostream" #include "string" #include "cstring" #include "stdio.h" using namespace std; bool remember[55]; struct bigNumber {     int num[100];     int ans;     bigNumber()     {        memset(num,0,sizeof(num));        ans=1;     }     bigNumber operator =(int k)     {     int i=0;     num[i]=k000;     while(k>=10000)     {        i++;        k/=10000;        num[i]=k000;     }     ans=i+1;     return *this;     } }; bigNumber number[55]; bigNumber bigNumber1,bigNumber2,bigNumber3; ostream& operator << (ostream& os, constbigNumber& big)//輸出高精度數運算子過載 {    os<<big.num[big.ans-1];     for(inti=big.ans-2;i>=0;i--)     {        if(big.num[i]==0)           os<<"000";        else if(big.num[i]<10)           os<<"000";        else if(big.num[i]<100)           os<<"00";        else if(big.num[i]<1000)           os<<"0";        os<<big.num[i];     }     return os; } istream& operator>>(istream& is, bigNumber &big)//輸入高精度運算子的過載 {    string s;    is>>s;    intlength=s.size();    for(int i=0;i    {       char a=s[i];       s[i]=s[length-1-i];       s[length-1-i]=a;    }    int m=1;    for(int i=0;i    {        int a=s[i]-'0';        big.num[i/4]+=a*m;        m*=10;        if(m==10000)            m=1;    }   big.ans=(length-1)/4+1;    return is; } bigNumber operator*(bigNumber big1,bigNumberbig2)//兩個高精度數相乘 {     bigNumber big3;     for(int i=0;i     {        for(int j=0;j        {          inta=big1.num[i]*big2.num[j];          big3.num[i+j]+=a000;         big3.num[i+j+1]+=a/10000;        }        for(int k=i;k<=i+big2.ans;k++)        {           if(big3.num[k]>=10000)            {              big3.num[k+1]+=big3.num[k]/10000;              big3.num[k]=big3.num[k]000;            }        }     }    big3.ans=big1.ans+big2.ans;    while(big3.num[big3.ans]==0)       big3.ans--;     big3.ans++;      if(big3.ans==0)        big3.ans++;      returnbig3; } bigNumber operator*(bigNumber big,intk)//高精度乘以普通常數(注意常數的大小範圍不可太大) {     bigNumber tool;     for(int i=0;i     {        int product=big.num[i]*k;        tool.num[i]+=product000;        int j=i;        while(product>=10000)        {           product/=10000;        tool.num[++j]+=product000;        }     }    tool.ans=big.ans+10;    while(tool.num[tool.ans]==0)        tool.ans--;     tool.ans++;     big=tool;     return big; } bigNumber operator+(bigNumber big1,bigNumberbig2)//兩個高精度數相加,將和賦在第一個數上 {     bigNumber tool=big1;     for(int i=0;i     {        tool.num[i]+=big2.num[i];        int j=i;        while(tool.num[j]>=10000)        {            inta=tool.num[j];           tool.num[j]=a000;           tool.num[j+1]+=a/10000;            j++;        }     }    tool.ans=max(big1.ans+1,big2.ans+1);    while(tool.num[tool.ans]==0)        tool.ans--;     tool.ans++;     return tool; } bigNumber operator/(bigNumber &big1,int k) {     int i=big1.ans-1;     int a;     while(i>=0)     {        a=big1.num[i];        big1.num[i]=0;    while(i>0&&a     {        a*=10000;        a+=big1.num[--i];        big1.num[i]=0;     }     big1.num[i]=a/k;     if(i==0)        break;     if(i>0)        big1.num[--i]+=(a%k)*10000;     }    while(big1.num[big1.ans]==0)        big1.ans--;     big1.ans++;     return big1; } bigNumber function0(int n) {     if(n==1||n==2)     {        bigNumber big;        big.num[0]=1;        return big;     }     if(remember[n])        return number[n];     bigNumber tool;     for(int k=1;k     {        bigNumber big1=function0(k);        bigNumber big2=function0(n-k);        bigNumber big3;        big3.num[0]=1;        for(int i=n-2;i>n-2-k+1;i--)        {           big3=big3*i;        }        for(int i=2;i<=k-1;i++)           big3=big3/i;        bigNumber big4;        big4.num[0]=1;        for(int i=1;i<=k;i++)           big4=big4*2;           big4.num[0]-=1;        tool=tool+(big1*big2*big3*big4);     }     remember[n]=true;     number[n]=tool;     return tool; } int main() {    for(inti=0;i<=50;i++)     remember[i]=false;     int n;    while(scanf("%d",&n)!=EOF&&n!=0)   cout<<function0(n)<<endl;;     return 0; }