楼天城之做男人就过八道题(第一题…

来源:互联网 发布:unity2d横版rpg源码 编辑:程序博客网 时间:2024/05/21 19:44
关于楼教主的第一题,感觉最费时间的还是高精度的实现。实现一万位以上整数基本运算的万进制高精度模版就写了快一天(题目里用到大概也有几百位吧),只能说太容易出错了,得不断地调试修改。题目源地址是北大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;
}

0 0