精简-【题解·洛谷】P10095 [ROIR 2023 Day 1] 斐波那契乘积

#温馨提示:此文章使用的是MD编辑器,在小程序上查看可能会出现乱码,敬请谅解

【题目链接】P10095 [ROIR 2023 Day 1] 斐波那契乘积

我们可以采用递归的方法解决斐波那契数乘积的问题。首先计算足够多的斐波那契数存入数组 a a a 中,然后针对每个输入的自然数 n n n ,利用递归函数search试图将 n n n 拆分成若干个大于 1 1 1 的斐波那契数的乘积。在搜索过程中,一旦找到能够整除 n n n 的斐波那契数 a [ x ] a[x] a[x] ,就将其从 n n n 中约掉,并对剩余的部分继续递归分解。

请注意以下易错点:

  • 务必确保生成的斐波那契数列足以覆盖题目给出的所有可能的 n n n 值,否则可能导致错误的答案。
  • 递归搜索时要注意边界条件的判断,防止陷入无限循环或者无效搜索。
  • while循环里正确检查和处理 n n n 是否可以被当前斐波那契数整除,且每次整除后更新临时变量 t m p tmp tmp
  • 在搜索过程中每当找到一种新的分解方式时,要确保及时更新答案变量 a n s ans ans

AC代码如下

#include <bits/stdc++.h>
#define ll long long // 用ll代替long long以简化代码
using namespace std;
ll a[105], ans; // 定义常量数组a来存储斐波那契数列,以及答案变量ans
// 搜索函数search,用于递归地分解n为斐波那契数的乘积
// x代表斐波那契数列的索引,从2开始,n代表当前要分解的数值
void search(ll x, ll n) {
    if (n == 1) { // 基础情况:当n等于1时,找到了一种合法的分解方式,增加答案计数器
        ans++;
        return;
    }
    if (a[x] > n) return; // 若当前斐波那契数a[x]大于n,则不可能继续分解,直接返回
    ll tmp = n; // 循环分割过程:尝试将n不断除以a[x],直到不能再整除为止
    while (tmp % a[x] == 0) {
        search(x + 1, tmp / a[x]); // 递归地处理除以a[x]之后的余数部分
        tmp /= a[x];
    }
    search(x + 1, n); // 若不能整除,直接进入下一位斐波那契数进行搜索
}

int main() {
    ll t, n, len=1; // 初始化斐波那契数列
    a[0] = 1;
    a[1] = 1;
    while (a[len] <= 1000000000000000000) { // 生成斐波那契数列至足够大的数,以覆盖题目所给的最大范围
        a[len + 1] = a[len] + a[len - 1];
        len++;
    }
    cin >> t; // 读取测试数据组数
    while (t--) { // 遍历所有测试数据
        cin >> n; // 读取每个自然数n
        ans = 0; // 重置答案计数器
        search(2, n); // 开始搜索并统计n可以表示为斐波那契数乘积的方式数
        cout << ans << endl; // 输出答案
    }
    return 0;
}

#普通版先鸽着

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值