[JAVA]给你一个数N求最少需要多少步可以变为Fibonacci数

链接:https://www.nowcoder.com/questionTerminal/18ecd0ecf5ef4fe9ba3f17f8d00d2d66?pos=11&orderByHotValue=1
来源:牛客网

Fibonacci数列是这样定义的:

F[0] = 0

F[1] = 1

for each i ≥ 2: F[i] = F[i-1] + F[i-2]

因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, …,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数
输入描述:输入为一个正整数N(1 ≤ N ≤ 1,000,000)

输出描述:输出一个最小的步数变为Fibonacci数"
示例1 输入15输出2

【解题思路】:
如果斐波那契数列中的一个数比当前数要大,则开始计算数列中的当前数和前一个数,哪一个数更近,则算出步数。

import java.util.*;
public class Fibonacci {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int f1 = 0;
        int f2 = 1;
        int f3 = f1 + f2;
        while (true) {
            if (f2 == n) {
                System.out.println(0);
            } else if (f2 > n) {
                if (Math.abs(f2 - n) > Math.abs(f1 - n)) {
                    System.out.println(Math.abs(f1-n));
                } else {
                    System.out.println(Math.abs(f2-n));
                }
                break;
            }
            f1 = f2;
            f2 = f3;
            f3 = f1 + f2;
        }
    }
}

在这里插入图片描述

### 回答1: 首先,我们知道 Fibonacci 列的性质是:每个都是前两个的和,即 $F_n=F_{n-1}+F_{n-2}$。因此,我们可以先出小于等于 $N$ 的所有 Fibonacci ,然后找到离 $N$ 最近的两个 Fibonacci $f_1$ 和 $f_2$,设 $f_1<N<f_2$。 接下来,我们可以考虑如何将 $N$ 变为 $f_1$ 或 $f_2$。假设 $N>f_1$,那么我们可以不断将 $N$ 减去 $f_1$,直到 $N$ 不再大于 $f_1$,此时 $N$ 只可能比 $f_1$ 小 $1$ 或 $2$,我们可以通过进行 $-1$ 操作将 $N$ 变为 $f_1$。 同理,如果 $N<f_2$,我们可以不断将 $N$ 加上 $f_1$,直到 $N$ 不再小于 $f_2$,此时 $N$ 只可能比 $f_2$ 大 $1$ 或 $2$,我们可以通过进行 $+1$ 操作将 $N$ 变为 $f_2$。 综上所述,我们只需要出小于等于 $N$ 的 Fibonacci 列,找到最近的两个 Fibonacci $f_1$ 和 $f_2$,然后比较 $N$ 与 $f_1$、$f_2$ 的关系,进行相应的操作即可。最终需要的步数就是 $N$ 与 $f_1$ 或 $f_2$ 的差值。 ### 回答2: 要将给定的字N变为Fibonacci,我们可以利用Fibonacci序列的特点进行操作。 首先,根据Fibonacci序列的定义,我们可以得知Fibonacci列从第3项(即F2)开始,每一项均是前两项的和。即 F(n) = F(n-1) + F(n-2),其中n≥3。 根据这个特点,我们可以从给定的字N出发,不断进行1或-1操作,使得N的值逼近Fibonacci序列中的某一项。具体操作如下: 1. 如果N本身就是Fibonacci,则不需要进行任何操作,步数为0; 2. 如果N不是Fibonacci,则根据N的大小,找到离N最近的两个FibonacciF(k)和F(k+1),使得 N ≥ F(k) 且 N ≤ F(k+1); 3. 假设N ≤ (F(k) + F(k+1))/2,则将N逼近F(k)的操作步数最少,此时操作步数为 N - F(k); 反之,若 N > (F(k) + F(k+1))/2,则将N逼近F(k+1)的操作步数最少,此时操作步数为 F(k+1) - N。 因此,我们只需找到最接近N的两个Fibonacci,然后根据上述操作计算最少需要多少可以将N变为Fibonacci。 需要注意的是,由于给定的N并没有具体的范围限制,可能值非常大,可能需要使用更高效的算法来计算最接近N的两个Fibonacci。 ### 回答3: 要将给定的 N 变成一个 Fibonacci ,我们可以通过逐渐逼近目标的方式来寻找最少步数。1 和 -1 操作可以用于将值逐渐调整到 Fibonacci 序列中。 首先,我们可以构建一个 Fibonacci 列,直到列中的最后两个大于 N。然后,我们从最后一个 Fibonacci f1 开始,将 f1 与 N 比较。 1. 如果 f1 等于 N,则无需进行任何操作,N 已经是 Fibonacci 。 2. 如果 f1 大于 N,则将 f1 减去 N,并记录此骤。然后,我们尝试用 f1 减去下一个 Fibonacci f2,如果结果大于或等于 0,则将 f2 减去 f1,并将结果记录下来。继续这个过程,直到结果小于 0。 3. 如果 f1 小于 N,则将 N 减去 f1,并记录此骤。然后,我们尝试用下一个 Fibonacci f2 减去 f1,如果结果大于或等于 0,则将 f1 更新为 f2,并将结果记录下来。继续这个过程,直到结果小于或等于 0。 最终,我们得到了一个 尽可能靠近 N 的 Fibonacci ,并且记录了所需的步数。我们选择步数最小的方案,可以将 N 最少步数变成 Fibonacci
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值