母羊生小羊问题

提示:第一篇文章,写的不好的地方还请多多包涵,见谅!!!

母羊生小羊问题

题目:开始有一只母羊,可以在第2年第4年各生下一头母羊,生产的母羊具有相同生育特性,并且所有的母羊生命为5年,即第5年死亡,求在x年后,所有的母羊总数。
另一个题目:一头母羊的寿命是5年,它会在第2年底第4年底各生下一头母羊,第5年底死去,问一开始农场有1头母羊,N年后,农场会有多少只母羊?)

前言

今天无意间看到这个题目,感觉挺有意思,就在网上找了找,结果发现有几种不同的答案,就来了劲要搞清楚个所以然来。(一字之差,就是不同的结果)


Java代码实现:

1.递归

代码如下(示例):

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @Author HYL
 * @Date 2022/8/14 11:55
 * @Version 1.0
 */
public class MyMain{

	static int num=1;
    public static int get(int year)
    {
        for(int i=1; i<=year; i++){
            if(i==2 || i==4){
                num+=1;
                get(year-i+1);
            }else if(i==5){
                num--;
            }
        }
        return num;
    }
    public static void main(String[] args) {
    	Scanner sc=new Scanner(System.in);
        int year=sc.nextInt();
        int sheeps = MyMain.get(year);
        System.out.println(sheeps);
    }
}

递归思想就是每一只是每一只的大家不搅和在一起。比如第一只母羊,到了生育年,生了一只新的母羊,新生的母羊自己再去走这个方法(递归,需要注意的是:总的年份只有year,新母羊是从出生时开始往后遍历年的(** 总年数 - 已过去的年数** ),所以是get(year-(2或4)+ 1))。在外边定义一个静态变量num=1,初始时只有一只母羊(在类加载时只加载一次),遍历方法对其进行增减,最终结果就是母羊数量。
但是: 当你看其他人的解答时会发现有的是get(year-(2或4))没有后面的+1,这里就要看自己的理解。
比如是求5年的:
第一年:只有第一只母羊(1只)
第二年:第一只母羊加上新生的母羊(2只)
(新生的母羊从出生起应该是1岁那还是0岁,我认为出生时就是他的第一年,是1岁。
就像这个5年,如果是0岁,前2年过去了,新生的母羊从第三年开始,他的年龄才是1岁,这样的递归就是对于新生的母羊只有后3年的时间;如果是1岁,第三年开始,他的年龄是2岁,也就是说他有4年,我认为这样更合理,新的母羊肯定是从他出生那一刻就要去走递归方法的。)
第三年:3只
第四年:5只
第五年:7只(最开始的第一只母羊到第五年了,死了。这里我也感觉不爽,说了寿命是5年,那第五年这只羊不是还活着吗,算第五年时不是应该还要算上这只羊,到第6年才应该减1吗?但是题目说第五年就死了,说的很矛盾)

    //对于另一个题目
    /*
	说的很明确,都是年底,那也就是如上面所说第二年生的新母羊,在第三年时才一岁,
	同样是5年,他出生时开始递归,就是还剩3年(get(year-2)),for循环是从0开始,
	当i=5时,已经是第六年了,所以总数-1(num--),但是这样算出来的20年178只羊,
	第5年只有3只。
	*/
    public static int get(int year)
    {
        for(int i=0; i<=year; i++){
            if(i==2 || i==4){
                num+=1;
                get(year-i);
            }else if(i==5){
                num--;
            }
        }
        return num;
    }

2.面向对象思想

代码如下(示例):

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @Author HYL
 * @Date 2022/8/14 11:55
 * @Version 1.0
 */
public class MyMain{
    public static int getSheeps(int n) {
        // sheeps表示整个羊群
        ArrayList<Sheep> sheeps = new ArrayList<Sheep>();
        //开始时有一只母羊
        sheeps.add(new Sheep());
        List<Sheep> addSheeps = new ArrayList<Sheep>();//新出生羊群
        List<Sheep> delSheeps = new ArrayList<Sheep>();//要老死的羊群
		//遍历年
        for (int i = 1; i <= n; i++) {
        	//遍历羊群
            for (Sheep s : sheeps) {
                s.age++;
                //该羊到了生育年,生小羊了入新生群
                if (s.age==2||s.age==4) {
                    Sheep sheep=new Sheep();
                    sheep.age=1;
                    addSheeps.add(sheep);
                } else if(s.age==5){ // 羊要死了,加入老死群中,等待删除
                    delSheeps.add(s);
                }
            }
            sheeps.addAll(addSheeps);
            sheeps.removeAll(delSheeps);
            System.out.println(sheeps);
            addSheeps.clear();//清空addSheeps
            delSheeps.clear();//清空待删除列表中的元素
        }

        return sheeps.size(); // 最后总羊数即整个羊群的羊数目
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int year=sc.nextInt();
        int sheeps = MyMain.getSheeps(year);
        System.out.println(sheeps);
    }
}
class Sheep{
    int age=0;
}

这里跟上边一样如果不是年底了就是出生时就是1岁:

if (s.age==2 || s.age==4) {
          Sheep sheep=new Sheep();
           sheep.age=1;
            addSheeps.add(sheep);
 }

如果是年底了,在下一年才1岁,出生时是0岁:

if (s.age==2 || s.age==4) {
        Sheep sheep=new Sheep();
         addSheeps.add(sheep);
}

python代码实现:

代码实现原理同上Java——>python

递归

totalnumber=1
def CountAll(year):    
	global totalnumber    
	for i in range(1,year+1):        
		if(i==2 or i==4):            
			totalnumber+=1            
			CountAll(year-i+1)              
		if(i==5):            
		totalnumber-=1    
	return totalnumber
def main():    
	year=int(input())    
	print(CountAll(year))
main()

列表加循环

class Sheep:
    def __init__(self, age):
        self.age = age
# 输入年份
year=int(input())
# 记录总的羊群数量
totalSheeps=[]
totalSheeps.append(Sheep(0))#刚开始有一头母羊
# 一只羊到24是,生小羊,新羊放进去
addSheeps=[]
# 当该羊到5是,该死亡了,放进去
delSheeps=[]
# 遍历年
for i in range(1,year+1):
    # 遍历总的羊群
    for s in totalSheeps:
        s.age+=1
        # 发现该羊到了生的时候,生小羊了(小羊从刚出生时标记为1岁)
        if(s.age==2 or s.age==4):
            ns=Sheep(1)
            addSheeps.append(ns)
        # 发现该羊到了死亡年龄,放进去
        if(s.age==5):
            delSheeps.append(s)
    # 给原来的羊群加上新出生的小羊
    totalSheeps+=addSheeps 
    # 给羊群去除死羊
    for b in delSheeps:
        totalSheeps.remove(b)
    addSheeps.clear()
    delSheeps.clear()
# 最后羊群的大小就是样的数量
print(len(totalSheeps))

总结

就一字之差,代码上的微小差异,结果确实大不相同,以20年为例:不按年底来说,20年一头母羊可以发展到2150只羊;按照年底考虑,20年一头母羊,可以发展到178只羊。
主要也就考大家的看待问题的角度,递归思想,不必过于纠结这些。
(这种题目本身就不合理,开局就一只母羊,好家伙还是自我繁殖,莫非是雌雄同体的,而且每次都是生母羊,这能力着实牛。)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值