原题地址:点击打开链接
一只羊 的寿命是五年 他会在二岁和四岁 分别产下一只羊 如果一个牧场第一年引进一只羊 请问N年后 这个羊圈 有几只羊?(不考虑羊的交配以及疾病等因素)
虽然这个问题很扯,羊都能单亲繁殖了也不知道是出芽还是分裂生殖.这个问题想法很简单但是当年数较大(比如说100)会出现一些问题的.对于这个问题我写的代码没有超过100年的,惭愧啊,所以罗列下面两个代码算是抛砖引玉了.
算法1:
#include <iostream>
using namespace std;
static int count=0;
class sheep
{
public:
int age;
sheep *LeftChild;
sheep *RightChild;
sheep()
{
age=0;
LeftChild=NULL;
RightChild=NULL;
}
};
void BuildTree(sheep *p)
{
if(p->age>=2&&p->age<4)//
{
sheep *Left=new sheep();
Left->age=p->age-2;
p->LeftChild=Left;
BuildTree(Left);
}
else if(p->age>=4)
{
sheep *Left=new sheep();
Left->age=p->age-2;
sheep *Right=new sheep();
Right->age=p->age-4;
p->LeftChild=Left;
p->RightChild=Right;
BuildTree(Left);
BuildTree(Right);
}
}
void CountSheeps(sheep *p)
{
if(p->age>5)
{
CountSheeps(p->LeftChild);
CountSheeps(p->RightChild);
}
else
{
count++;
if(p->RightChild!=NULL)
{
CountSheeps(p->LeftChild);
CountSheeps(p->RightChild);
}
else if(p->LeftChild!=NULL)
{
CountSheeps(p->LeftChild);
}
}
}
每只羊只有0,1,2这三种个数的子孙,也就是很符合二叉树的性质,我就以第一只羊为根写了一个二叉树.每只羊都是一个节点,如果有的话他的左子是它2岁时生下的,同理它的右子是它四岁时生下的.我假设羊不会老死,最后根据N年会有一棵二叉树,树上的age小于5的节点是我们计算入count的,我们遍历二叉树age<5的就count++,最后得出答案.但是这个算法的效率极差极差!!!!!
后来我又写了第二个算法.
算法2:
#include <iostream>
#include <stack>
using namespace std;
int main()
{
cout<<"Input A Num:";
int year;
cin>>year;
int *array=new int[year+1];
int i;
for(i=0;i<=year;i++)
array[i]=0;
stack<int> myStack;
myStack.push(year);
while(!myStack.empty())
{
i=myStack.top();
myStack.pop();
array[i]++;
if(i>4)
myStack.push(i-4);
if(i>2)
myStack.push(i-2);
}
int sum=array[0]+array[1]+array[2]+array[3]+array[4]+array[5];
cout<<"The Sum of Sheep is:"<<sum<<endl;
}
这个是利用栈和伪hash写的,效率较前面的有提升但是在算到89年时会栈溢出.
又写了个算法,基于斐波那契数列的
算法3:
#include <iostream>
using namespace std;
int f(int n,int year)
{
if(n>year)
return 0;
if(n==year)
return 1;
if(n>=0)
return f(n+2,year)+f(n+4,year);
return -1;
}
int main()
{
cout<<"Input A Num:";
int year;
cin>>year;
int sum=f(0,year)+f(1,year)+f(2,year)+f(3,year)+f(4,year)+f(5,year);
/* cout<<f(5,year)<<endl;
cout<<f(4,year)<<endl;
cout<<f(3,year)<<endl;
cout<<f(2,year)<<endl;
cout<<f(1,year)<<endl;
cout<<f(0,year)<<endl;
*/
cout<<"Num Of Sheep Is:"<<sum<<endl;
return 0;
}
这个算法依然不会突破100,在88的时候至少就已经溢出了.
最后附上我目前写的最好效率的算法了:
算法4:
#include <iostream>
using namespace std;
int main()
{
cout<<"Input A Num:";
int year;
cin>>year;
long long *array=new long long[6];
array[0]=1;
array[1]=0;
array[2]=0;
array[3]=0;
array[4]=0;
array[5]=0;
for(int i=1;i<=year;i++)
{
//give birth
array[0]+=array[2]+array[4];
//growup
array[5]=array[4];
array[4]=array[3];
array[3]=array[2];
array[2]=array[1];
array[1]=array[0];
array[0]=0;
/*
cout<<i<<" ";
cout<<endl;
cout<<array[0]<<endl;
cout<<array[1]<<endl;
cout<<array[2]<<endl;
cout<<array[3]<<endl;
cout<<array[4]<<endl;
cout<<array[5]<<endl;
cout<<"--------------------"<<endl;
*/
}
long long sum=array[0]+array[1]+array[2]+array[3]+array[4]+array[5];
cout<<"The Sum of Sheep is:"<<sum<<endl;
return 0;
}
计算效率很高,但是在计算1459的时候会发生溢出,要是将long long类型换成某个适应大数的类型的话应该不错的.
大家有什么更好的算法欢迎贴在下面啊.