user-0 提问: 习题4-11 兔子繁衍问题

回复:
user: user-1
content: //非洲大地是一个异常凶猛的动物王国，老虎，狮子，豹子是顶层的食肉动物， //它们不但捕食兔子、羚羊、斑马等食草性动物来生存， //食肉动物也可以互相吃掉比较弱小的食肉动物， //这些动物的排泄物可以补养草木，让其生长，满足食草动物的需要。 //请模拟该生态系统的动态循环过程，寻找调节某类动物数量的方式 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> enum eA	{Tiger,Lion,Leopard,Hare,Antelope,Zebra,Grass,Waste}; char *names[8]={"老虎","狮子","豹子","兔子","羚羊","斑马","草","排泄物"}; struct _A { 	unsigned int count; } A[8]; void init()	{ 	int	k;  	srand(time(NULL)); 	for	(k=0;k<8;k++) { 		switch (k) { 		case Tiger	 :A[k].count=	  4;break; 		case Lion	 :A[k].count=	 10;break; 		case Leopard :A[k].count=	 20;break; 		case Hare	 :A[k].count=  2000;break; 		case Antelope:A[k].count=	500;break; 		case Zebra	 :A[k].count=	100;break; 		case Grass	 :A[k].count=300000;break; 		case Waste	 :A[k].count=  1000;break; 		} 	} } void show(int day) { 	int	k;  	printf("==========第%d天==========\n",day); 	for	(k=0;k<8;k++) { 		printf("%6s:%u\n",names[k],A[k].count); 	} } void loop()	{ 	int	k,d,n,f,r; 	unsigned int i; 	d=0;  	while (1) { 		show(d); 		if (getch()==27) break;	//按Esc键退出 		d++; 		for	(k=0;k<8;k++) { 			switch (k) { 			case Tiger: 				if (A[k].count>0) {//老虎数量＞0 					for	(i=0;i<A[k].count;i++) {//每只老虎 						f=0;//饥饿中 						n=0; 						while (1) { 							r=rand()%20; 								   if (	0<=r &&	r< 6) {//吃兔子20只 								if (A[Hare].count>=20+2) { 									A[Hare].count-=20; 									f=1; 								} 							} else if (	6<=r &&	r<11) {//吃羚羊2只 								if (A[Antelope].count>=2+2)	{ 									A[Antelope].count-=2; 									f=1; 								} 							} else if (11<=r &&	r<16) {//吃斑马1只 								if (A[Zebra].count>=1+2) { 									A[Zebra].count-=1; 									f=1; 								} 							} else if (16<=r &&	r<19) {//吃豹子2只 								if (A[Leopard].count>=2+2) { 									A[Leopard].count-=2; 									f=1; 								} 							} else if (19<=r &&	r<19) {//吃狮子1只 								if (A[Lion].count>=1+2)	{ 									A[Lion].count-=1; 									f=1; 								} 							} 							if (f==1) break; 							n++; 							if (n>=10) break; //最多尝试觅食10次 						} 						if (f==0) { 							if (A[k].count>2) //最后两只被人类保护 							A[k].count--;//饿死 						} else { 							A[Waste].count+=5;//吃饱后排泄5 							if ((A[k].count*2<A[Hare	].count/20 							  || A[k].count*2<A[Antelope].count/2 							  || A[k].count*2<A[Zebra	].count/1 							  || A[k].count*2<A[Leopard	].count/2 							  || A[k].count*2<A[Lion	].count/1) 							 &&	n<=1 							 &&	rand()%30==0) A[k].count++;	//如果老虎的数量翻倍且食物够吃，且仅1次觅食就吃饱，1/30概率生一只老虎 							if (A[k].count>20) A[k].count=20;//老虎不可能＞20 						} 					} 				} 			break; 			case Lion: 				if (A[k].count>0) {//狮子数量＞0 					for	(i=0;i<A[k].count;i++) {//每只狮子 						f=0;//饥饿中 						n=0; 						while (1) { 							r=rand()%20; 								   if (	0<=r &&	r< 6) {//吃兔子20只 								if (A[Hare].count>=20+2) { 									A[Hare].count-=20; 									f=1; 								} 							} else if (	6<=r &&	r<11) {//吃羚羊2只 								if (A[Antelope].count>=2+2)	{ 									A[Antelope].count-=2; 									f=1; 								} 							} else if (11<=r &&	r<16) {//吃斑马1只 								if (A[Zebra].count>=1+2) { 									A[Zebra].count-=1; 									f=1; 								} 							} else if (16<=r &&	r<19) {//吃豹子2只 								if (A[Leopard].count>=2+2) { 									A[Leopard].count-=2; 									f=1; 								} 							} else if (19<=r &&	r<19) {//吃老虎1只 								if (A[Tiger].count>=1+2) { 									A[Tiger].count-=1; 									f=1; 								} 							} 							if (f==1) break; 							n++; 							if (n>=5) break; //最多尝试觅食5次 						} 						if (f==0) { 							if (A[k].count>2) //最后两只被人类保护 							A[k].count--;//饿死 						} else { 							A[Waste].count+=5;//吃饱后排泄5 							if ((A[k].count*2<A[Hare	].count/20 							  || A[k].count*2<A[Antelope].count/2 							  || A[k].count*2<A[Zebra	].count/1 							  || A[k].count*2<A[Leopard	].count/2 							  || A[k].count*2<A[Tiger	].count/1) 							 &&	n<=1 							 &&	rand()%20==0) A[k].count++;	//如果狮子的数量翻倍且食物够吃，且仅1次觅食就吃饱，1/20概率生一只狮子 							if (A[k].count>40) A[k].count=40;//狮子不可能＞40 						} 					} 				} 			break; 			case Leopard: 				if (A[k].count>0) {//豹子数量＞0 					for	(i=0;i<A[k].count;i++) {//每只豹子 						f=0;//饥饿中 						n=0; 						while (1) { 							r=rand()%20; 								   if (	0<=r &&	r<10) {//吃兔子10只 								if (A[Hare].count>=20+2) { 									A[Hare].count-=20; 									f=1; 								} 							} else if (10<=r &&	r<16) {//吃羚羊1只 								if (A[Antelope].count>=2+2)	{ 									A[Antelope].count-=2; 									f=1; 								} 							} else if (16<=r &&	r<19) {//吃斑马1只 								if (A[Zebra].count>=1+2) { 									A[Zebra].count-=1; 									f=1; 								} 							} 							if (f==1) break; 							n++; 							if (n>=20) break; //最多尝试觅食20次 						} 						if (f==0) { 							if (A[k].count>2) //最后两只被人类保护 							A[k].count--;//饿死 						} else { 							A[Waste].count+=4;//吃饱后排泄4 							if ((A[k].count*2<A[Hare	].count/20 							  || A[k].count*2<A[Antelope].count/2 							  || A[k].count*2<A[Zebra	].count/1) 							 &&	n<=1 							 &&	rand()%15==0) A[k].count++;	//如果豹子的数量翻倍且食物够吃，且仅1次觅食就吃饱，1/15概率生一只豹子 							if (A[k].count>100)	A[k].count=100;//豹子不可能＞100 						} 					} 				} 			break; 			case Hare: 				if (A[k].count>0) {//兔子数量＞0 					for	(i=0;i<A[k].count;i++) {//每只兔子 						f=0;//饥饿中 						n=0; 						while (1) { 							if (A[Grass].count>=50+2) {//吃草50 								A[Grass].count-=50; 								f=1; 							} 							if (f==1) break; 							n++; 							if (n>=500)	break; //最多尝试觅食500次 						} 						if (f==0) { 							if (A[k].count>2) //最后两只被人类保护 							A[k].count--;//饿死 						} else { 							A[Waste].count+=1;//吃饱后排泄1 							if ((A[k].count*5<A[Grass].count/20) 							 &&	n<=1 							 &&	rand()%10==0) A[k].count++;	//如果兔子的数量翻5倍且食物够吃，且仅1次觅食就吃饱，1/10概率生一只兔子 							if (A[k].count>20000) A[k].count=20000;//兔子不可能＞20000 						} 					} 				} 			break; 			case Antelope: 				if (A[k].count>0) {//羚羊数量＞0 					for	(i=0;i<A[k].count;i++) {//每只羚羊 						f=0;//饥饿中 						n=0; 						while (1) { 							r=rand()%40; 								   if (	0<=r &&	r<39) {//吃草50 								if (A[Grass].count>=50)	{ 									A[Grass].count-=50; 									f=1; 								} 							} else if (39<=r &&	r<40) {//1/40概率生一只羚羊 								f=1; 								A[k].count++; 							} 							if (f==1) break; 							n++; 							if (n>=200)	break; //最多尝试觅食500次 						} 						if (f==0) { 							if (A[k].count>2) //最后两只被人类保护 							A[k].count--;//饿死 						} else { 							A[Waste].count+=3;//吃饱后排泄3 							if ((A[k].count*2<A[Grass].count/50) 							 &&	n<=1 							 &&	rand()%15==0) A[k].count++;	//如果羚羊数量翻倍且食物够吃，且仅1次觅食就吃饱，1/15概率生一只羚羊 							if (A[k].count>5000) A[k].count=5000;//羚羊不可能＞5000 						} 					} 				} 			break; 			case Zebra: 				if (A[k].count>0) {//斑马数量＞0 					for	(i=0;i<A[k].count;i++) {//每只斑马 						f=0;//饥饿中 						n=0; 						while (1) { 							r=rand()%60; 								   if (	0<=r &&	r<59) {//吃草50 								if (A[Grass].count>=80)	{//吃草80 									A[Grass].count-=80; 									f=1; 								} 							} else if (59<=r &&	r<60) {//1/60概率生一只斑马 								f=1; 								A[k].count++; 							} 							if (f==1) break; 							n++; 							if (n>=100)	break; //最多尝试觅食100次 						} 						if (f==0) { 							if (A[k].count>2) //最后两只被人类保护 							A[k].count--;//饿死 						} else { 							A[Waste].count+=4;//吃饱后排泄4 							if ((A[k].count*2<A[Grass].count/80) 							 &&	n<=1 							 &&	rand()%25==0) A[k].count++;	//如果斑马数量翻倍且食物够吃，且仅1次觅食就吃饱，1/25概率生一只斑马 							if (A[k].count>2000) A[k].count=2000;//斑马不可能＞2000 						} 					} 				} 			break; 			case Grass: 				if (A[k].count<=0) {//干旱导致寸草不生 					A[k].count=300000;//一场大雨草疯长 				} 			break; 			case Waste: 				if (A[k].count>0) {//排泄物数量＞0 					for	(i=0;i<A[k].count;i++) {//每堆排泄物 						f=0;//沤肥中 						n=1;//最多尝试长草1次 						while (1) { 							r=rand()%20; 							if ( 0<=r && r<	10)	{//长草100 								A[k].count--; 								if (A[Grass].count<3000000+100)	//草不可能超过3000000 									A[Grass].count+=100; 								f=1; 							} 							if (f==1) break; 							n--; 							if (n<=0) break; 						} 						if (f==0) { 							A[k].count--;//没长草就降解 						} 					} 				} 			break; 			} 		} 	} } int main() { 	init(); 	loop(); 	return 0; } //==========第0天========== //	老虎:4 //	狮子:10 //	豹子:20 //	兔子:2000 //	羚羊:500 //	斑马:100 //	草:300000 //排泄物:1000 //==========第1天========== //	老虎:5 //	狮子:11 //	豹子:15 //	兔子:1851 //	羚羊:539 //	斑马:100 //	草:300730 //排泄物:2504 //==========第2天========== //	老虎:5 //	狮子:12 //	豹子:8 //	兔子:1839 //	羚羊:593 //	斑马:101 //	草:342720 //排泄物:3321 //==========第3天========== //	老虎:5 //	狮子:12 //	豹子:6 //	兔子:1891 //	羚羊:641 //	斑马:102 //	草:401940 //排泄物:3826 //==========第4天========== //	老虎:5 //	狮子:12 //	豹子:2 //	兔子:1890 //	羚羊:687 //	斑马:104 //	草:471650 //排泄物:4143 //==========第5天========== //	老虎:5 //	狮子:13 //	豹子:2 //	兔子:1973 //	羚羊:743 //	斑马:98 //	草:548650 //排泄物:4417 //==========第6天========== //	老虎:5 //	狮子:14 //	豹子:2 //	兔子:2041 //	羚羊:821 //	斑马:91 //	草:632720 //排泄物:4694 //==========第7天========== //	老虎:6 //	狮子:15 //	豹子:2 //	兔子:2079 //	羚羊:866 //	斑马:94 //	草:716640 //排泄物:4930 //==========第8天========== //	老虎:6 //	狮子:16 //	豹子:2 //	兔子:2109 //	羚羊:936 //	斑马:93 //	草:818210 //排泄物:5168 //==========第9天========== //	老虎:6 //	狮子:17 //	豹子:2 //	兔子:2094 //	羚羊:999 //	斑马:93 //	草:929030 //排泄物:5377 //==========第10天========== //	老虎:6 //	狮子:18 //	豹子:2 //	兔子:2186 //	羚羊:1060 //	斑马:92 //	草:1044520 //排泄物:5619 //==========第11天========== //	老虎:6 //	狮子:18 //	豹子:2 //	兔子:2149 //	羚羊:1139 //	斑马:95 //	草:1165350 //排泄物:5846 //==========第12天========== //	老虎:6 //	狮子:19 //	豹子:3 //	兔子:2225 //	羚羊:1221 //	斑马:91 //	草:1290120 //排泄物:6117 //==========第13天========== //	老虎:7 //	狮子:20 //	豹子:4 //	兔子:2115 //	羚羊:1327 //	斑马:87 //	草:1432610 //排泄物:6356 //==========第14天========== //	老虎:8 //	狮子:20 //	豹子:2 //	兔子:2048 //	羚羊:1421 //	斑马:87 //	草:1592680 //排泄物:6581 //==========第15天========== //	老虎:8 //	狮子:20 //	豹子:2 //	兔子:2042 //	羚羊:1548 //	斑马:86 //	草:1758700 //排泄物:6879 //==========第16天========== //	老虎:9 //	狮子:26 //	豹子:2 //	兔子:1875 //	羚羊:1672 //	斑马:80 //	草:1923550 //排泄物:7136 //==========第17天========== //	老虎:9 //	狮子:26 //	豹子:2 //	兔子:1736 //	羚羊:1824 //	斑马:71 //	草:2110780 //排泄物:7405

user: user-2
content: 个人认为你的代码存在这么几个问题： 1.题目已经明说了：从键盘输入一个不大于10000的整数N。那么输入N的时候，应该有一个检验，比如是否有非法字符(如字母、符号等)，以及检验下输入值是否在0~10000之间。 2.既然题目都说了，“一对兔子”，而且它们在生育小兔子时候，也是“每个月都生育一对兔子”，是不是应该N/2呢？ 3.题目说从出生3个月开始，每月生育一对生小兔子，那么计算月份时候就不能简单的用log2()来算。得算清楚，哪些兔子有生育能力，哪些没有。这么写肯定是不对的。

user: user-3
content: 看不懂你的逻辑，很简单的测试，当N=1时，你的输出结果不对，N=2时，你的输出结果不对，不能只以样例去检测你的代码  以前有人问过我一道算法题：母羊在第二年和第四年生母羊，然后在第五年死去，随便输入一个年数问有多少头母羊。我给出的算法是 int a0 = 1, b1 = 0, c2 = 0, d3 = 0, e4 = 0, f5 = 0; 	//羊有6种状态，新生羊(0岁)，1岁，2岁，3岁，4岁，GG(5岁) 	int i, year = 8;//year是你需要计算的几年，我们以i为计数，走一个以1年为周期的时间线for 	for (i = 0; i < year; i++) 	{ 		f5 = e4; 		e4 = d3; 		d3 = c2; 		c2 = b1; 		b1 = a0;//每过一年，先不算生了多少羊，先看去年的羊今年变成啥了，就是年龄加一岁，即整体数量的右移   		a0 = c2 + e4;//然后再看年龄变了后，该生的生，该GG的GG，新生羊的数量就是现在2岁羊和4岁羊的数量   	}//你会发现f5一只作为一个坐值在被赋值，他的值我们并没有用，这就代表GG ，我们直接把它丢弃了  	printf("%d\n", a0 + b1 + c2 + d3 + e4);//最后剩下的总数就是 0岁+1岁+2岁+3岁+4岁

user: user-4
content: 很简单，你的输入输出方式是错的

user: user-0
content: 耽误大家时间了！我看到最后的N对，就知道自己看错题目了，而后再看了下，发现是3月后每月都生一对小兔子。  实在抱歉，以后早点睡觉，深夜刷题没什么好下场！见笑了。感谢各位的帮助，赵四老师的例子我抽空研究下，谢谢。

user: user-0
content: 话说这个结贴率50%什么意思？我之前的帖子能点的都点了。