递归p2437

这篇博客介绍了如何使用递归算法解决‘蜜蜂路线’问题,类似于经典的数楼梯问题。作者提供了状态转移方程和代码实现,强调了高精度计算的注意事项,并在主函数中展示了简单的调用方式。博客末尾作者表达了对更复杂递归题目的期待。

刚好写到这题就随手写一下作业

题目

P2437 蜜蜂路线 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析

一眼就是递归

而且那个经典的数楼梯一样 基本没什么差别   其实只要把数楼梯的改一下

最应该注意的就是高精把..

void fun(int x)
{
	for(int i=1;i<=len;i++)
	  f[x][i]=f[x-1][i]+f[x-2][i];
	for(int i=1;i<=len;i++)
	  if(f[x][i]>9)
	  {
	  	f[x][i+1]+=f[x][i]/10;
	  	f[x][i]%=10;
	  }
	if(f[x][len+1]) len++;
}

递归的基本公式   判断终止条件和状态转移方程

主函数就更简单了  

int main ()
{
    scanf("%d%d",&m,&n);
    f[1][1]=1,f[2][1]=2;
    for(int i=3;i<=n-m;i++) plus(i);
    for(int i=len;i;i--) printf("%d",f[n-m][i]);
    return 0;
}

总结

可能还没有遇到难的递归题目...

cs202   zhoujie

<think>嗯,用户问的是用递归写P1226,可能指的是快速幂算法。我得先确认P1226是什么题目。通常像洛谷这样的OJ会有题目编号,P1226应该就是快速幂的模板题。题目大概是给定a、b、p,求a的b次方模p的结果,对吧? 那用户希望用递归的方式来实现快速幂。通常快速幂可以用迭代或者递归两种方法。递归的话,思路应该是将问题分解为更小的子问题。比如,a^b,如果b是偶数,可以拆成(a^(b/2))^2,如果是奇数,就是a*(a^(b/2))^2。这样每次递归将指数减半,时间复杂度是O(log n)。 那递归的终止条件应该是当指数为0时返回1,模p的话就是返回1%p。然后每一步递归计算的时候都要取模,防止数值过大。所以递归函数的大体结构应该是这样的: long long quick_pow(long long a, long long b, long long p) { if (b == 0) return 1 % p; long long half = quick_pow(a, b / 2, p); if (b % 2 == 0) { return (half * half) % p; } else { return (half * half % p) * a % p; } } 不过要注意,这里的中间结果可能还是会很大,比如half*half可能会溢出,所以可能需要每次乘法之后都取模。比如,在奇数的情况下,先算half*half%p,再乘以a,再%p。这样更安全。 另外,用户可能需要处理大数的情况,所以数据类型要用long long。同时,递归的层数会不会有问题?比如,当b非常大的时候,比如1e18,递归深度会是log2(b),大约是60层,这在C++中是没问题的,不会导致栈溢出。所以递归方法在这里是可行的。 测试一下例子,比如题目中的样例输入:2^10 mod 9,结果应该是7。递归计算的话,分解步骤是否正确? 比如,计算2^10: 10是偶数,分解为(2^5)^2。然后计算2^5,5是奇数,分解为2*(2^2)^2。2^2是(2^1)^2。2^1是奇数,分解为2*(2^0)^2=2*1=2。然后返回,2^1是2,2^2是4,然后2^5是2*(4^2)=2*16=32,模9的话是5。然后2^10是5^2=25模9等于7。对的,正确。 另一个测试用例,比如3^3 mod 5。3^3=27,模5是2。递归的话,3^3分解为3*(3^1)^2。3^1是3*(3^0)^2=3*1=3。然后3^1是3,平方后9,乘3得27,模5是2。正确。 那代码应该没问题。需要注意的是,当p=1的时候,因为任何数模1都是0,但递归终止条件是b=0时返回1%p,此时p=1的话,1%1=0,所以正确。比如,a=5,b=0,p=1,结果0,正确。 那用户的问题解决了。现在需要解释为什么这样写,递归的分解过程,以及每一步都取模的重要性。可能还要提到递归的终止条件和分治思想。 相关问题的话,可能包括递归的优缺点,快速幂的时间复杂度,如何处理大数运算,或者迭代方式的实现,以及模运算的性质等等。</think><< 使用递归实现快速幂(P1226)的关键在于将指数分解为更小的子问题。以下是递归实现快速幂的代码: ```cpp #include <iostream> using namespace std; long long quick_pow(long long a, long long b, long long p) { if (b == 0) return 1 % p; // 边界条件处理 long long half = quick_pow(a, b / 2, p); half = half * half % p; // 合并子问题的解 // 根据指数的奇偶性调整结果 return (b % 2 == 0) ? half : half * a % p; } int main() { long long a, b, p; cin >> a >> b >> p; cout << a << "^" << b << " mod " << p << "=" << quick_pow(a, b, p); return 0; } ``` **实现原理:** 1. **递归终止条件**:当指数 `b` 为 0 时,返回 `1%p`(处理 `p=1` 的特殊情况) 2. **分治策略**: - 将 `a^b` 分解为 `(a^(b/2))^2` - 若 `b` 为奇数,额外乘以 `a` 3. **模运算优化**:每次乘法后立即取模,防止数值溢出 4. **时间复杂度**:O(logb),通过二分法将线性计算优化为对数级 **示例验证(输入 2 10 9):** 计算过程: 1. 2^10 → (2^5)^2 2. 2^5 → 2*(2^2)^2 3. 2^2 → (2^1)^2 4. 2^1 → 2*(2^0)^2 最终结果:2^10 mod 9 = 7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值