题目描述:
假设母牛从出生起第4个年头开始每年可以生一头小母牛,但是第11年后死亡。按此规律,第n年时有多少头母牛?(假设n不大于30)
定义一个母牛类CCow,能够用动态创建和撤消类对象的方式来模拟小母牛的出生和死亡规律。试编写C++程序完成上述计算。
输入要求:
第一行输入测试次数
每次测试输入一行,表示第几年的整数n(<=30)
输出要求:
每次测试输出一行,第n年的母牛总数
输入样例:
3
7
30
25
输出样例:
6
28364
4530
代码示例:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
class CCow
{
public:
CCow(int n)
{
num = n;
}
static void SetSum()
{
sum = 1;
}
int getNum()
{
return num;
}
void changeadd(int n)
{
num += n;
}
void changeminus(int n)
{
num -= n;
}
static void add(int n)
{
sum += n;
}
static void minus(int n)
{
sum -= n;
}
static int getSum()
{
return sum;
}
private:
int num;//本年牛的个数
static int sum;//牛的总数
};
int CCow::sum = 1;
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
CCow** c = new CCow * [n];
c[0] = new CCow(1);
CCow::SetSum();//设置第一天牛的个数
for (int i = 1; i < n; i++)
{
c[i] = new CCow(c[i - 1]->getNum());//第i天的牛初始数用i-1天构造
if (i >= 10)//第十一年牛死亡
{
c[i]->minus((c[i - 10]->getNum()));//总数减去十年前牛的数目
for (int j = i; j >= i - 10; j--)
{
c[j]->changeminus((c[i - 10]->getNum()));//十年内的num减1,代表牛死亡
}
}
if (i >= 3)//第四年牛产仔
{
c[i]->changeadd(c[i - 3]->getNum());//增加本年牛的个数
c[i]->add(c[i - 3]->getNum());//牛的总数增加
}
}
cout << CCow::getSum() << endl;
for (int i = 0; i < n; i++)
{
delete c[i];
}
delete[]c;
}
return 0;
}
代码分析:
我们用枚举的方法看一下前11年的数据变化
前三年无任何变化;
第四年之后有新牛出生,三年前的num即代表在本年有繁殖能力的牛,因此本年牛的数目等于前一年的数目加上三年前牛的数目,以此类推;
第十一年之后有牛死亡,由于死亡的优先级大于生育的优先级,因此先减去十年前新生牛的数目,代码第71行是将在本年死亡的牛在它所在的10年内出名,for循环只是所有年份都减去,本是总共减去了10年前新生牛的数目,而不是累加!之后再加上三年前有繁殖能力的牛个数是本年的总个数,以此类推,原理相同!
多悟一悟生死之间的关系以及其在每个类指针的num代表的含义!!