首页 > 试题广场 >

计算斐波那契数最小差值

[编程题]计算斐波那契数最小差值
  • 热度指数:2894 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给定一个整数 n ,计算 n 与斐波那契数的最小差值(绝对值)

说明:
斐波那契数定义:
从0,1开始后面的数值为前面两者之和, 即第三个数为第一和第二个数之和
形如:0,1,1,2,3,5,8,13,21。。。。  其中3为1与2的和,5为2与3的和,8为3与5的和等等
要计算的数值案例:
输入15,与斐波那契数相减,与13相减的绝对值是2,与21相减的绝对值是6,与众多斐波那契数相减的最小差值为2
因此输入15,输出2

数据范围:输入的数满足





输入描述:
输入任意整数


输出描述:
一个整数
示例1

输入

15

输出

2

说明

15与“0,1,1,2,3,5,8,13,21。。。。”当中的13差值的绝对值最小,与21的差值为6,与8的差值为7  
示例2

输入

1

输出

0

说明

斐波那契数列中存在 1 ,因此最小差值是 0  
n = int(input())
a = 0
b = 1
pre = min(abs(n - a),abs(n - b))
while True:
    c = a+b
    t = abs(n - c)
    if t > pre:
        print(pre)
        break
    else:
        pre = t
    a = b
    b = c    


发表于 2019-07-14 19:39:18 回复(0)
#include <stdio.h>
#include <math.h>
int fb(int n)
{
	int result=1;
	int pr=1;
	int ppr;
	if(n==0)
	{
		return result-1;
	}
	else 
	{	
		if(n>=1&&n<3)
		{
			return result;
		}
		else
		{
			while(n>2)
			{
				ppr=pr;
				pr=result;
				result=ppr+pr;
				n-=1;
			}
			return result;
		}
	}
}
int value(int n)
{
	int i=0;int temp=0;
	if(n<2)
		{	
			return abs(fb(1)-1);
		}
	else
	{	temp=abs(fb(1)-n);
		for(i=2;i<=n+1;i++)
		{  
			if(abs(fb(i)-n)<=temp)
				temp=abs(fb(i)-n);	
		}
		
		return temp;
	}
}
int main()
{
	int n=0,a=0,i=0;
	scanf("%d",&n);
	a=value(n);
	printf("%d\n",a);
}

发表于 2020-12-01 12:14:15 回复(0)
边创建斐波那契数列边比较,遇到符合的直接输出
import java.util.*;
//给定一个正整数n,计算n与斐波那契数的最小差值(绝对值)
//斐波那契数:0,1,1,2,3,5,8,13,21。。。。
public class Main {
        public static void main(String args[]){
            Scanner sc=new Scanner(System.in);
            while(sc.hasNext()){
                int n=sc.nextInt();
                int [] a=new int[n+3];
                a[0]=0;
                a[1]=1;
                for(int  i=2;i<=n+2;i++){
                    a[i]=a[i-1]+a[i-2];
                     if(n>=a[i-2]&&n<=a[i-1]){
                        System.out.print(Math.min((n-a[i-2]),(a[i-1]-n)));
                         break;
                   }
                }
            }
        }
}

编辑于 2020-08-05 11:22:07 回复(0)
13ms,9308k
/*
与他最接近的两个斐波那契数,计算差值,找最小
*/
import java.io.*;
public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader( new InputStreamReader( System.in ));
        int n = Integer.parseInt(br.readLine());
        int min,k=0,max;//k用来记录斐波那契数的下标
        while(true){
            int temp = ***);
            if(***) <= n && ***+1) >= n){
                min = ***);
                max = ***+1);
                break;
            }else
                k++;
        }
        System.out.println(Math.abs(min-n)>Math.abs(max-n)?Math.abs(max-n):Math.abs(min-n));
    }
    
    public static int Fuc(int index){
        if(index == 0)
            return 0;
        if(index == 1)
            return 1;
        return Fuc(index-1)+Fuc(index-2);
    }
}


编辑于 2020-05-05 15:48:45 回复(0)
说好的输入的是正整数呢,还夹一个0在里面
a,m,p,q = int(input()),[1],0,1
while m[-1] >= 0:
    p,q = q,p + q
    m.append(a - q)
print(min(abs(m[-1]),m[-2]) if a else 0)


发表于 2020-03-19 12:06:47 回复(0)
Java解法 动态规划
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    /**
     * 运行时间:48ms
     *
     * 占用内存:10568k
     * */
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        ArrayList<Integer> record = new ArrayList<>();
        record.add(0);
        record.add(1);
        int i=2;
        while (true){
            record.add(record.get(i-1)+record.get(i-2));
            if (record.get(i)>=n)
                break;
            i++;
        }
        if (n==0||n==1||n==2){
            System.out.println(0);
        }else {
            System.out.println(Math.min(Math.abs(record.get(i)-n),Math.abs(record.get(i-1)-n)));
        }
    }
}


发表于 2020-03-01 13:47:57 回复(0)
  • 方法有点蠢,就是不停地创建斐波那契数列数组,因为这是一个无穷数列,所以数组的大小一直在改变。

  • 比如说我想获取数列中的第8个数时多少,那么就要创建一个长度为8的数组(斐波那契数列)。

  • 根据题目中的示例,可以知道15是夹在13和21之间的,也就是13=<15<=21,写个循环,只要满足这个条件(大于等于数列中前一个数并且小于等于后一个数),就开始作差,把最小的一个数返回即可。

    import java.util.*;
    public class Main
    {
       public static void main(String [] args)
       {
           Scanner sc=new Scanner(System.in);
           while(sc.hasNextInt())
           {
               int n=sc.nextInt();
               System.out.println(getMin(n));
           }
       }
    
       private static int getMin(int num)
       {
           int min=0;
           for(int i=0;;i++) 
           {
               if(num>=getNum(i)&&num<=getNum(i+1))
               {
                   int a=Math.abs(num-getNum(i));
                   int b=Math.abs(num-getNum(i+1));
                   min=a<b?a:b;
                   break;//退出循环
               }         
           }
           return min;          
       }
    
       private static int getNum(int index)//获取索引为几的数
       {
           int [] array=new int[index+1];
           if(array.length>2)
           {
               array[0]=0;
               array[1]=1;
               for(int i=2;i<array.length;i++)
               {
                   array[i]=array[i-1]+array[i-2];
               }
           }
           else if(array.length==2)
           {
                array[0]=0;
                array[1]=1;
           }
           else if(array.length==1)
           {
                array[0]=0;
           }
    
           return array[index];      
       }  
    }
发表于 2020-02-16 12:11:52 回复(0)
n = int(input())
fib = [0, 1]  # 保存两个值,方便做比较
while fib[1] < n:  # 当第二个fib大于或等于n时,退出循环
    temp_fib = fib[0] + fib[1]
    fib[0] = fib[1]
    fib[1] = temp_fib
print(min(n - fib[0], fib[1] - n))  # 选出较小的差值作为结果

发表于 2019-09-24 15:13:54 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,a,b;
    cin>>n;
    a = 0;
    b = 1;
    while(!(a<=n && n<=b)){
        int t = b;
        b = a + b;
        a = t;
    }
    cout<<min(n-a, b-n)<<endl;

    return 0;
}

发表于 2019-09-04 23:19:33 回复(0)
n = int(input())
a, b = 0, 1
while b < n:
    a, b = b, a + b
print(min(n - a, b - n))

发表于 2019-09-03 03:30:09 回复(0)
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,i=1,res=0;
    cin>>n;
    vector<int>num;
    num.push_back(0);
    num.push_back(1);
    if(n<=3)
    {
        cout<<0<<endl;
        return 0;
    }
    while(num[i]<n)
    {        
        i++;
        num.push_back(num[i-1]+num[i-2]);
    }
    res=min(abs(n-num[num.size()-2]),abs(n-num[num.size()-1]));
    cout<<res<<endl;
    return 0;
}

发表于 2019-07-13 16:40:57 回复(0)
package main

import (
    "fmt"
)

func main() {
    var n int
    fmt.Scan(&n)
    if n<=1{
        fmt.Print(0)
        return
    }
    a,b,c:=0,1,1
    ans:=n-1
    for i:=4;;i++{
        a=b
        b=c
        c=a+b
        if abs(n,c)<ans{
            ans=abs(n,c)
        }else{
            break
        }
    }
    fmt.Print(ans)
}

func abs(a,b int)int{
    if a-b>0{
        return a-b
    }
    return b-a
}

发表于 2023-03-21 14:31:10 回复(0)
#include <stdio.h>

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        int a = 0;
        int b = 1;
        int c = a+b;
        while(1) {
            if(n == b) {
                printf("%d\n", 0);
                break;
            } else if( n < b) {
                if(abs(a-n) < abs(b-n)) {
                    printf("%d\n", abs(a-n));
                    break;
                } else {
                    printf("%d\n", abs(b-n));
                    break;
                }
            }
            a = b;
            b = c;
            c = a + b;
        }
    }
    return 0;
}
发表于 2023-01-21 16:37:28 回复(0)
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int cal(int n)
{
    vector<int> f;
    f.push_back(0);
    f.push_back(1);
    int tem = 0;
    int res = 0;

    // 构造斐波那契数列
    while(f.back()<=n)
    {
        tem = f.back() + f[f.size()-2];
        f.push_back(tem);
    }

    if(abs(f.back()-n) > abs(f[f.size()-2]-n))  res = abs(f[f.size()-2]-n);
    else   res = abs(f.back()-n);

    return res;
}

int main()
{
    int n;
    cin >> n;
    int res =0;
    res = cal(n);
    cout << res;
    return 0;
}

发表于 2021-10-30 20:18:47 回复(0)
public static int solve(int n) {
   if(n==0)
       return 0;
   int n1=0;
   int n2=1;
   int tmp=0;
    while(tmp<=n) {
	tmp=n1+n2;
	n1=n2;
	n2=tmp;
    }
    return Math.min(n-n1, tmp-n);
}

发表于 2021-01-13 21:25:59 回复(0)
真的有问题,题目描述是计算最小差值,那么如果相当差值绝对值为0肯定就输出0了。但是标准输出要求输出数组正整数。 那0怎么办
发表于 2020-08-28 10:40:31 回复(0)
while 1:
    try:
        n=int(input())
        if n==0:
            print(0)
        elif n==1:
            print(0)
        else:
            i,re=2,[0,1,1]
            while re[i]<n:
                re.append(re[i-1]+re[i])
                i+=1
            print(min(abs(re[i-1]-n),abs(re[i]-n)))
    except:
        break

发表于 2020-08-17 17:31:34 回复(0)
#include<iostream>
#include<vector>
using namespace std;
int fib(int n)
{
    if(n<2)
        return n;
    if(n==2)
        return 1;
    return fib(n-1)+fib(n-2);
}
int main()
{
    int idx=0;
    vector<int> fibarr;
    int N;
    cin>>N;
    while(true)
    {
        int tmp=fib(idx);
        fibarr.push_back(tmp);
        idx++;
        if(tmp>N)
            break;
    }
    
    int res=abs(fibarr[fibarr.size()-1]-N)>abs(fibarr[fibarr.size()-2]-N)?abs(fibarr[fibarr.size()-2]-N):abs(fibarr[fibarr.size()-1]-N);
    cout<<res;
}
发表于 2020-08-13 20:54:50 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int min = Integer.MAX_VALUE;
        min = Math.min(Math.abs(num-0),Math.abs(num-1));
        int a=1;
        int b=1;
        while(true){
            a=a^b;
            b=a^b;
            a=a^b;
            b=a+b;
            if(min > Math.abs(num-b)){
                min=Math.abs(num-b);
            }else if(min < Math.abs(num-b)){
                break;
            }
        }
        System.out.println(min);
    }
}

发表于 2020-08-06 20:51:26 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int a = scan.nextInt();
        int result = 0,left = 0,right = 0;
        if(a==0||a==1){
            System.out.println(0);
            return;
        }
        for(int i=1;;i++){
            if(fbnc(i)>a){
                left = a - fbnc(i-1);
                right = fbnc(i) - a;
                result = (right>=left)?left:right;
                break;
            }
        }
        System.out.println(result);
    }
   
    public static int fbnc(int n){
        if(n==0) return 0;
        if(n==1) return 1;
        return fbnc(n-1)+fbnc(n-2);
    }
}
发表于 2020-06-11 12:21:27 回复(0)