羊数目问题

来源:互联网 发布:阿里云发送短信代码 编辑:程序博客网 时间:2024/06/11 19:33

原题地址:点击打开链接

一只羊 的寿命是五年  他会在二岁和四岁 分别产下一只羊 如果一个牧场第一年引进一只羊 请问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 birtharray[0]+=array[2]+array[4];//growuparray[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类型换成某个适应大数的类型的话应该不错的.

大家有什么更好的算法欢迎贴在下面啊.

原创粉丝点击