注册 登录
编程论坛 C++教室

[求助]C++题目

cilubutong 发布于 2007-06-12 22:30, 2061 次点击
今天晚上老师给我们一个题目:
有一个农场,有一头小母牛,它到了四岁的时候就可以生一头小牛,以后的每年都可以生一头,到了十三年后这这头可以生多少头牛,(它生的小年到了四年的时候也可以生小牛)
希望师兄们给我点意见并且最好给点注释,因为老师会问我这步是干什么的?
40 回复
#2
cilubutong2007-06-12 22:31

生的小牛都是母牛.

#3
HJin2007-06-13 03:33

/*---------------------------------------------------------------------------
File name: bccn-Heifer-right.cpp
Author: HJin
Date: 6/13/2007
*/

/**
Recurrence formula for f(n), where n is the year
number. Now is year 1.

f(n) = f(n-3) + f(n-1), if n>=4
= 1, if n<=3

This formula is very similar to the famous Fibonacci formula.

One can solve this recurrence equation mathematically, using the
three roots, x_1, x_2, x_3, of
x^3 - x^2 -1 = 0.
You can solve the cubic equation using Cardano formula:
x_1 ~ 1.47, x_2 ~-0.23 + 0.79 i, x_3 = complex conjugate of x_2


To compute it programatically, you can use aipb2007's recursive formula.
Or use my two formulae below.


Sample output:

Year No.| iterative | recursive
--------+-----------+-----------
1 | 1 | 1
2 | 1 | 1
3 | 1 | 1
4 | 2 | 2
5 | 3 | 3
6 | 4 | 4
7 | 6 | 6
8 | 9 | 9
9 | 13 | 13
10 | 19 | 19
11 | 28 | 28
12 | 41 | 41
13 | 60 | 60
14 | 88 | 88
15 | 129 | 129
16 | 189 | 189
17 | 277 | 277
18 | 406 | 406
19 | 595 | 595
20 | 872 | 872
21 | 1278 | 1278
22 | 1873 | 1873
23 | 2745 | 2745
24 | 4023 | 4023
25 | 5896 | 5896
26 | 8641 | 8641
27 | 12664 | 12664
28 | 18560 | 18560
29 | 27201 | 27201
30 | 39865 | 39865
31 | 58425 | 58425
Press any key to continue . . .


*/


#include <iostream>
using namespace std;

/**
Iterative soln: time complexity is O(n); i.e., linear growth.
Space complexity is O(1).
*/
int f_iterative(int n);

/**
Recursive soln: time complexity is O(2^n); i.e., exponential growth.
*/
int f_recursive(int n);

int main()
{
int i;

cout<<"Year No.| iterative | recursive\n";
cout<<"--------+-----------+-----------\n";

for(i=1; i<32; ++i)
{
cout<<i<<"\t| "<<f_iterative(i)<<"\t | "<<f_recursive(i)<<endl;
}


return 0;
}


int f_iterative(int n)
{
int f0=1; // tracks f(n-3)
int f1=1; // tracks f(n-2)
int f2=1; // tracks f(n-1)
int res=1;
int i;

for(i=3; i<n; ++i)
{
res = f0+f2;

// update the tracking
f0 = f1;
f1 = f2;
f2 = res;
}

return res;
}

int f_recursive(int n) // simply the formula
{
if(n<=3)
return 1;
else
return f_recursive(n-3) + f_recursive(n-1);
}

[此贴子已经被作者于2007-6-14 2:09:54编辑过]

#4
cilubutong2007-06-13 10:01
我们老师好象说答案是60头啊   你没把题目理解错误吧  老师说只有几个语句就可以了
#5
cilubutong2007-06-13 12:10

那个大哥帮帮小弟吧!

#6
HJin2007-06-13 12:27

deleted. To save 1 byte of bc-cn web-space.

[此贴子已经被作者于2007-6-14 23:43:45编辑过]

#7
cilubutong2007-06-13 12:44

小牛到了它四岁的时候就可以生小牛,它生的小牛到了四岁的时候也可以生小牛依次类推!

#8
沉墨2007-06-13 15:43
回复:(cilubutong)小牛到了它四岁的时候就可以生小...
小牛现在多大,一岁?
#9
zouxiaohua2007-06-13 16:07

先数学分析一下
30年后:
第一头可以产 13 - 3 = 10 头
第一头产的第一头小牛可以产: 13 - 8 = 5头
。。。。。。2 13 - 9 = 4
..........

#10
cilubutong2007-06-13 18:38

是的

#11
aipb20072007-06-13 19:11
回复:(cilubutong)[求助]C++题目

#include <iostream>
using namespace std;

void compute(int year,int &count){
if (year > 3){
for (;year > 3;--year)
compute(year-3,++count);
return;
}
}

int main(){
int count = 1;
compute(13,count);
cout << count << endl;
return 0;
}


用递归写的,没有算法,个人觉得只是解决了问题,谈不上效率!
希望有更好的答案!
#12
aipb20072007-06-13 19:12
正确答案是60个牛!
#13
aipb20072007-06-13 19:26
回复:(zouxiaohua)先数学分析一下30年后:第一头可...
一头牛活30年?
#14
发发2007-06-13 21:29

怎么可能是60头啊...不会这么多

我算的是36头.

1-2-3-4-5-6-7-8-9 -10-11-12-13 年
1-1-1-2-3-4-5-7-10-14-19-26-36 头

应该是这样的.

#15
发发2007-06-13 21:32

从第4年起每年增加的能生的母牛数跟第1年起总牛数一一对应...

如果是3年一生 那就是fib 数列了``1 1 2 3 5 8 13...............

#16
aipb20072007-06-13 21:59
LS的,
1-2-3-4-5-6-7-8-9 -10-11-12-13 年
1-1-1-2-3-4-5-7-10-14-19-26-36 头

第7年开始就错了哦!
7的年,本身母牛生一头,它在4的年生的女儿生一头(可以生育了)。所以在上一年的基础上多了两头,该是4+2=6头。
这里都错了,后面就不说了哈!
#17
cilubutong2007-06-13 22:02

谢谢了,不愧是高手啊! 没错就是60头

#18
cilubutong2007-06-13 22:07
版主能给我点注释吗?我有点看不懂了
#19
发发2007-06-13 22:18

LS的,
1-2-3-4-5-6-7-8-9 -10-11-12-13 年
1-1-1-2-3-4-5-7-10-14-19-26-36 头

第7年开始就错了哦!
7的年,本身母牛生一头,它在4的年生的女儿生一头(可以生育了)。所以在上一年的基础上多了两头,该是4+2=6头。
这里都错了,后面就不说了哈!



第4年出生的那头 要在后面第4年才能再生啊....也就应该是第8年啊! 如果你这样看那就的确是~
我以为后面1年是第1年 道理都一样

#20
aipb20072007-06-13 22:20
LS,就按你的后一年,那第4年就不该是2头而是1头!
你自己矛盾了哦!
呵呵~,写个更好的出来吧!
#21
发发2007-06-13 22:27

按照斑竹的:

1-2-3-4-5-6-7-8-9 -10-11-12-13 年
1-1-1-2-3-4-6-9-13-19-28-41-60 头
这题 只抓每年能生的母牛数就行了``

#22
发发2007-06-13 22:28

呵呵,的确是...~~不好意思 太大意了

#23
aipb20072007-06-13 22:29
回复:(cilubutong)版主能给我点注释吗?我有点看不懂...
呵呵~

本来代码就没几行的,不好注释啊!
我给你说说我的思路吧!

用count记数,for循环中代表每个牛生活的年限,每年生一个牛,当然,用>3控制第4年起生。
然后每生的那个牛就重复上面的过程。

这就是递归的思想,如果你不懂递归,也就很难懂我这个了。


有空我再想想更好的方法(非递归),或者算法来解决,大家也都想想!
#24
孤魂居士2007-06-13 23:00
最先是1头牛:
年数: 1年 2年 3 4 5 6 7 8 9 10 11 12 13

第1头牛 : 牛2 牛3 牛4 牛5 牛6 牛8 牛 牛 牛 牛

第2头牛: 牛7 牛9 牛 牛 牛 牛

第3头牛: 牛10 牛 牛 牛 牛

第4头牛: 牛 牛 牛 牛

第5头牛: 牛 牛 牛

第6头牛: 牛 牛

第7头牛: 牛 牛

第8头牛: 牛

第9头牛: 牛


知道算法不知道怎么写代码
还有就是第6头和第7头是同时出世的 还有第8头和第9和10头也是同时出世

请师兄门写个简单点的程序 让我很容易理解的``
#25
孤魂居士2007-06-13 23:01
上面的还没有写完呢```还有很多没有写...............省掉了
#26
孤魂居士2007-06-13 23:08

最先是1头牛:
年数: 1年 2年 3 4 5 6 7 8 9 10 11 12 13

第1头牛 : 牛2 牛3 牛4 牛5 牛6 牛8 牛11 牛 牛 牛

第2头牛: 牛7 牛9 牛12 牛 牛 牛

第3头牛: 牛10 牛13 牛 牛 牛

第4头牛: 牛14 牛 牛 牛

第5头牛: 牛 牛 牛

第6头牛: 牛 牛

第7头牛: 牛 牛

第8头牛: 牛

第9头牛: 牛

第10头牛: 牛

第11头牛:下面的都没有4年时间生牛了 怎么好象没有60头啊
第12头牛:
.
.
.
.
.
.
.
.

.

#27
孤魂居士2007-06-13 23:12
牛7是第牛2生的
牛10是第3牛生的
#28
孤魂居士2007-06-13 23:16
我的怎么只有36头
#29
aipb20072007-06-13 23:38
以下是引用孤魂居士在2007-6-13 23:16:40的发言:
我的怎么只有36头

从16楼开始看!

#30
孤魂居士2007-06-13 23:47
明白了
多谢无限兄的提示
#31
发发2007-06-14 00:15
算法很简单啊`从第4头开始以后每年能生牛的母牛的增加量=从第1年开始的总牛数

也就是 1 1 1 2 3 4 6 9.........
1 1 1 2 3 4 6 9.......
因为以后4年后每往后1年就有4年前出生的牛能够生育....
#32
aipb20072007-06-14 09:40
/*
分析:
年:1 2 3 4 5 6 7 8 9 10 11 12 13
0 0 0 1 1 1 1 1 1 1 1 1 1 最初母牛每年产牛数
…………………………………………………………………
1 1 1 1 1 1 1 4年前母牛产牛数
1 1 1 1 1 1 ……………………
1 1 1 1 1 ……………………
2 2 2 2 ……………………
3 3 3 ……………………
4 4 ……………………
6 ……………………
注:年限对应数字仅表示当年新出生牛数
*/

#include <iostream>
using namespace std;

int compute(int year){
int a[year],count = 0,i;
//将最先的母牛在year年中每年生育牛数记录
for (i = 0;i < year;++i)
a[i] = (i < 3 ? 0 : 1); //第4年开始生

//主要步骤
for (i = 0;i < year;++i){
if (i > 3 && a[i-3] > 0){//a[i-3]表示第i年前4年出生的牛数
for (int j = i;j < year;++j)
a[j] += a[i-3]; //a[j]记录在第j年的产牛状况
}
}
//计算总牛数
for (i = 0;i < year;++i)
count += a[i];
return count + 1; //加上最初的母牛
}


int main(){
cout << compute(13) << endl;
system("pause");
return 0;
}

另一种思路。


我实在不明白楼上的意思
呵呵~迟钝了!

[此贴子已经被作者于2007-6-14 9:43:47编辑过]

#33
HJin2007-06-14 10:49
aipb2007: Very good algorithm. You can use O(1) space insread. As you implemented it, your space reuirement is O(n).

#34
aipb20072007-06-14 12:33
回复:(HJin)aipb2007: Very good algorithm. You c...

What you said is "big O notation",right?

I know the concept but not clearly,can you show some example to describe how to compute it and use it.
So I can use this method to think abt program's complexity!

Thank you!

#35
aipb20072007-06-14 14:39
回复:(HJin)aipb2007: Very good algorithm. You c...
I saw your new respond for this problem at 3f. Very good, as you said, it's really like fibnacci numbers.
It's so easy to understand fibnacci numbers, but when come to this problem,I never think abt that.

In addition, every time you solve a problem, you have a good style to write you analysis and detailed comment.Do you follow some templet or whatever?
#36
发发2007-06-14 18:41

int a[20]={1,1,1},i=0;
for(i>3;i<13;i++)
a[i]=a[i-1]+a[i-3];

a[12]就是要求的``60

我功底不行 看不懂复杂的 只会写这种~~~~~!

#37
aipb20072007-06-14 22:02
以下是引用发发在2007-6-14 18:41:09的发言:

int a[20]={1,1,1},i=0;
for(i>3;i<13;i++)
a[i]=a[i-1]+a[i-3];

a[12]就是要求的``60

我功底不行 看不懂复杂的 只会写这种~~~~~!

You catch the main step of a good algorithm. Though you may not wrote the right code, however, what you thought is really good.
See the code on 3 floor, he has made the perfect program for that algorithm!

#38
Dam30002007-06-14 22:39
这是一个类似 斐波那契数列 的东东
F[n]=F[n-1]+F[n-3] while(n>=4)
F[n]=1 while(n<4)
可以这么说吗?

看了21楼后得出的结论……
#39
HJin2007-06-14 23:34
以下是引用aipb2007在2007-6-14 14:39:45的发言:
I saw your new respond for this problem at 3f. Very good, as you said, it's really like fibnacci numbers.
It's so easy to understand fibnacci numbers, but when come to this problem,I never think abt that.

In addition, every time you solve a problem, you have a good style to write you analysis and detailed comment.Do you follow some templet or whatever?

1. This problem is really a math problem. Do you agree?

2. There are some good C++/C coding style "standards" out there. I personally used some source code beautifier: say sourceFormatX (this program is very very very risky --- it may delete your windows registry if you use the shareware version!!! Google sourceFormatX and 看雪 for it), greatcode (open source @ sourceforge, and my own simple beautifier written in C++.

Best of the luck!

#40
cilubutong2007-06-15 07:27

呵呵!小孤,我开始数了好几次也算错了,我们老师叫我们回去摆牙签!

#41
yeye05212007-06-15 11:40
我也都算错了好几次了。
1