兔子繁殖(int128+重载运算符 处理Fibonacci)

题目描述

兔子有很强的繁殖能力。1对成年的兔子每个月可以生育一对幼年的兔子,而1对幼年的兔子经过m个月之后,就会长成1对成年的兔子。当一开始有1对成年兔子时,经过d个月以后,共有多少对兔子?你的任务是计算出一对成年兔子经过d个月后,共有多少对兔子,假设整个过程中没有兔子死亡。

输入描述

输入有多组数据,每组占1行,为两个整数m,d(1≤m≤10,1≤d≤100),当m=d=0时表示结束。

输出描述

每行为每组数据对应最后得到的兔子数。

样例

输入

2 3
3 5
0 0

输出

5
9
//分析:
/*
    首先是对兔子繁殖的推断:
        我们都知道Fibonacci公式,那么我们对原始的f[i]=f[i-1]+f[i-2]来看
        f[i-1]为当前兔子数,f[i-2]为当前可生殖兔子数,即兔子生长周期为2
        那么我们对于m之前的月份,每月应该只会有一只兔子生殖
        而m之后的月份,每个月的兔子生殖数应该是m月之前的兔子个数,即f[i-m];
        因此得到公式
        f[i]=f[i-1]+1           i<m
        f[i]=f[i-1]+f[i-m]      i>=m
    之后我们看到数据范围月份d在[1,100],当d=100时,n=1时兔子数最大是2^100>long long
    所以是一个高精加的题目,但是当数据小于2^128时,我们可以借助结构体来构造一个int128数据类型
    之后重载一下+,就可以很轻松的完成这个问题了。
*/

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e18;

struct int128 {
	ll low,hig;
} a[101]= {{1,0},{1,0}};//a[0/1].low=1,a[0/1].hig=0;
int m,d;

int128 operator + (int128 a,int128 b) {
	int128 t;
	t.low=t.hig=0;
	t.low=a.low+b.low;
	t.hig=t.low/mod+a.hig+b.hig;
	t.low%=mod;
	return t;
}//对+的重载
void solve() {
	a[0]=a[1]= {1,0};//初始化
	d++;//由于题目要求从0月可是,d要加1
	for(int i=2; i<=d; i++) {
		if(i<m)
			a[i]=a[i-1]+a[0];
		else
			a[i]=a[i-1]+a[i-m];
	}
	if(a[d].hig)
		cout<<a[d].hig;
	cout<<a[d].low<<"\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);

	while(cin>>m>>d&&(m||d))
		solve();
	return 0;
}

手写int128+重载运算符可转接:传送门

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

panjyash

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值