2025-3-8算法打卡

一,试题B: 类斐波那契循环数

1.题目描述:

对于一个有n 位的十进制数N = d1d2d3 ... dn,可以生成一个类斐波那契数列S ,数列S 的前n 个数为{S1 = d1, S2 = d2, S3 = d3...,Sn = dn},数列S 的第k(k > n) 个数为Σk-1i=k-n Si。如果这个数N 会出现在对应的类斐波那契数列S中,那么N 就是一个类斐波那契循环数。

例如对于197,对应的数列S 为f1; 9; 7; 17; 33; 57; 107; 197; : : : g,197 出现在S 中,所以197 是一个类斐波那契循环数。

请问在0 至107 中,最大的类斐波那契循环数是多少?

2.实例:

3.思路:

在0至10^7范围内,最大的类斐波那契循环数(即Keith数)是925993。这类数的特性是它出现在由其各位数字生成的类斐波那契数列中。通过高效生成数列并检查每一步的值,可以验证该数满足条件。

4:代码:

import java.util.LinkedList;

public class Main {
    public static void main(String[] args) {
        // 从1e7向下遍历寻找最大的Keith数
        long max = 10_000_000L;
        for (long n = max; n >= 0; n--) {
            if (isKeithNumber(n)) {
                System.out.println(n);
                return;
            }
        }
        System.out.println(0); // 若未找到则输出0
    }

    private static boolean isKeithNumber(long N) {
        String s = Long.toString(N);
        int length = s.length();
        // 一位数直接返回true
        if (length == 1) return true;
        
        int[] digits = new int[length];
        for (int i = 0; i < length; i++) {
            digits[i] = s.charAt(i) - '0';
        }
        
        // 检查全零情况
        boolean allZero = true;
        for (int d : digits) {
            if (d != 0) {
                allZero = false;
                break;
            }
        }
        if (allZero) return N == 0;
        
        // 初始化队列和总和
        LinkedList<Long> queue = new LinkedList<>();
        long sum = 0;
        for (int d : digits) {
            long num = d;
            queue.add(num);
            sum += num;
        }
        
        if (sum == N) return true;
        
        // 生成后续项并检查
        while (true) {
            long first = queue.poll();
            long next = 2 * sum - first;
            
            if (next < 0) return false; // 处理溢出
            if (next == N) return true;
            if (next > N) return false;
            
            queue.add(next);
            sum = next;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值