二哥培养出了一种繁殖能力很强的兔子。
这种兔子在出生后的第一个月,能够生出a对兔子;第二个月,能够生出b对兔子;第三个月以及以后的每个月,都可以生出c对兔子。
二哥对此很感兴趣,若他有一对刚出生的兔子,按照最理想的模式繁殖,并假设兔子不死,二哥想知道最少需要几个月这些兔子可以遍布地球的每个角落。
为了回答这个问题,二哥想要知道这种兔子在第N个月时的对数。
输入只有一行,四个数,分别为a,b,c,N ( 0≤a≤b≤c≤100,N≤1000 ),其含义为题目所述。
输出只有一个数,为第N个月兔子的对数。
0 1 1 11
144
题目所给的数据为斐波那契数列,对于兔子问题,大家自行百度斐波那契 兔子问题即可明白,这里有这样一个表达式:
res[i]=res[i-3]*c+(res[i-2]-res[i-3])*b+(res[i-1]-res[i-2])*a+res[i-1];
比如第4个月的兔子数,为第一个月的兔子生下的res[1]*c,和第二个月的新生兔子乘以b,加上第三个月新生兔子乘以a再加上这之前的老兔子数即可。
但是这里其实更麻烦的一点是对于大数字的处理,由于N在1000的时候已经远远大于正常的表达范围,所以必须自己用类模仿大数字。
#include <iostream>
#include "string.h"
using namespace std;
class bigInt
{
friend bigInt operator+(bigInt a,bigInt b);
friend bigInt operator-(bigInt a,bigInt b);
friend bigInt operator*(bigInt a,bigInt b);
public:
int ans[3000];
int length;
bigInt()
{
memset(ans,0,sizeof(int)*1000);
length=0;
}
bigInt(int a)
{
memset(ans,0,sizeof(int)*1000);
int i=0;
while(a!=0)
{
ans[i++]=a%10;
a=a/10;
}
length=i;
}
bigInt(const bigInt& a)
{
length=a.length;
for(int i=0;i<length;i++)
{
ans[i]=a.ans[i];
}
}
bigInt& operator=(const bigInt &a)
{
if(&a==this) return (*this);
length=a.length;
for(int i=0;i<length;i++)
{
ans[i]=a.ans[i];
}
return (*this);
}
void print()
{
for(int i=length-1;i>=0;i--)
{
cout<<ans[i];
}
cout<<endl;
}
};
bigInt operator*(bigInt a,int b)
{
bigInt c;
int carry=0;
for(int i=0;i<a.length;i++)
{
int tp=a.ans[i]*b+carry;
carry=tp/10;
c.ans[i]=tp%10;
}
int j=a.length;
while(carry!=0)
{
c.ans[j++]=carry%10;
carry=carry/10;
}
c.length=j;
return c;
}
bigInt operator-(bigInt a,bigInt b)
{
bigInt c;
int carry=0;
int length_small=(a.length>b.length)?b.length:a.length;
for(int i=0;i<length_small;i++)
{
if(a.ans[i]<(b.ans[i]+carry))
{
c.ans[i]=10+a.ans[i]-b.ans[i]-carry;
carry=1;
}
else
{
c.ans[i]=a.ans[i]-b.ans[i]-carry;
carry=0;
}
}
if(a.length>b.length)
{
for(int i=b.length;i<a.length;i++)
{
if(a.ans[i]<carry)
{
c.ans[i]=10+a.ans[i]-carry;
carry=1;
}
else
{
c.ans[i]=a.ans[i]-carry;
carry=0;
}
}
}
else if(a.length<b.length)
{
for(int i=a.length;i<b.length;i++)
{
if(a.ans[i]<carry)
{
c.ans[i]=10+b.ans[i]-carry;
carry=1;
}
else
{
c.ans[i]=b.ans[i]-carry;
carry=0;
}
}
}
for(int i=max(a.length,b.length);i>=0;i--)
{
if(c.ans[i]!=0)
{
c.length=i+1;
break;
}
}
return c;
}
bigInt operator+(bigInt a,bigInt b)
{
bigInt c;
int carry=0;
int length_small=(a.length>b.length)?b.length:a.length;
for(int i=0;i<length_small;i++)
{
int tp=a.ans[i]+b.ans[i]+carry;
c.ans[i]=tp%10;
carry=tp/10;
}
if(a.length>b.length)
{
for(int i=b.length;i<a.length;i++)
{
int tp=a.ans[i]+carry;
c.ans[i]=tp%10;
carry=tp/10;
}
if(carry==1)
{
c.ans[a.length]=carry;
c.length=a.length+1;
}
else
{
c.length=a.length;
}
}
else if(a.length<b.length)
{
for(int i=a.length;i<b.length;i++)
{
int tp=b.ans[i]+carry;
c.ans[i]=tp%10;
carry=tp/10;
}
if(carry==1)
{
c.ans[b.length]=carry;
c.length=b.length+1;
}
else
{
c.length=b.length;
}
}
else
{
if(carry==1)
{
c.ans[a.length]=1;
c.length=a.length+1;
}
else
{
c.length=a.length;
}
}
return c;
}
int main()
{
int a,b,c;
int N;
cin>>a>>b>>c>>N;
bigInt *res=new bigInt[N+1];
res[0]=1;
res[1]=a+1;
res[2]=b+a+a*a+1;
for(int i=3;i<=N;i++)
{
res[i]=res[i-3]*c+(res[i-2]-res[i-3])*b+(res[i-1]-res[i-2])*a+res[i-1];
}
res[N].print();
return 0;
}