题目背景
翻译自 ROIR 2023 D1T2。
斐波那契数指斐波那契数列(f0=1,f1=1,fi=fi−2+fi−1)中出现的数。
题目描述
给定一个自然数 n,求出将其表示为大于 1 的斐波那契数的乘积的方式数量。
输入格式
第一行一个数 t,表示数据组数。
接下来 t 行,每行输入一个数 n。
输出格式
对于每组测试数据,输出一个数表示答案。
输入输出样例
输入 #1
5 2 7 8 40 64输出 #1
1 0 2 2 3
说明/提示
样例解释:
- 2=2。
- 7 无法被表示为斐波那契乘积。
- 8=8=2×2×2。
- 40=5×8=2×2×2×5。
- 64=8×8=2×2×2×8=2×2×2×2×2×2。
本题使用捆绑测试。
子任务编号 | 分值 | 2≤n≤ |
---|---|---|
1 | 15 | 100 |
2 | 17 | 105 |
3 | 9 | n 是 2 的整数次幂 |
4 | 38 | 109 |
5 | 21 | 1018 |
对于所有数据,1≤t≤50,2≤n≤1018。
题目难度
普及/提高-
参考思路
思路
斐波那契数列增长极快,1018 内只有 86 个数,直接暴搜。
出口
- 当 n=1,不能继续除,介时退出。介时退出。
- 当 k=0 或 k=1 时,数列都是 1,无意义会死循环,介时退出。
为避免多余操作,寻找第一个小于 a 的数x。
除得尽,接着除。 否则,往下找能除尽的。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL f[100];
int res = 0;
void dfs(LL x, int k)
{
if (k == 87) return ;
if (x == 1) { res++; return ; }
if (x % f[k] == 0)
dfs(x / f[k], k);
dfs(x, k + 1);
}
int main()
{
f[0] = f[1] = 1;
for (int i = 2; i <= 86; i++)
f[i] = f[i - 1] + f[i - 2];
int t; LL x;
scanf("%d", &t);
while (t--)
{
res = 0;
scanf("%lld", &x);
dfs(x, 2);
printf("%d\n", res);
}
return 0;}