首页 > 试题广场 >

星际跃迁的稳定信标

[编程题]星际跃迁的稳定信标
  • 热度指数:1026 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
在浩瀚无垠的宇宙中,为了实现安全的超光速“星际跃迁”,星际舰队的导航系统必须锁定一个特定的“跃迁信标频率” f。该频率是一个正整数。

根据舰队旗舰“探索者号”的引擎限制,所选的信标频率 f 必须小于或等于引擎能承受的最大频率 F_{max},即满足约束条件 f \le F_{max}

此外,为了维持跃迁过程的绝对稳定,频率 f 必须是一个“和谐频率”。一个频率被称为“和谐”的,当且仅当它的各位数字从高位到低位是一个非递减序列。例如,123111399 都是和谐频率,而 121897 这种非和谐频率会导致跃迁通道的灾难性崩溃。

最后,一个至关重要的约束是,频率 f 的“能量签名” S(f) 必须为一个质数。能量签名 S(f) 定义为该频率 f 的各位数字之和。一个质数能量签名可以确保跃迁过程与宇宙背景辐射产生最佳共鸣,从而最小化能量消耗。

您的任务是编写一个程序,对于给定的最大频率 F_{max},找出不大于 F_{max} 的、能量签名为质数的、值最大的和谐频率 f

输入描述:
输入一个正整数 F_{max},代表引擎能承受的最大频率。

数据范围:1 \le F_{max} \le 10^{18}


输出描述:
返回一个整数,表示满足所有条件的最大和谐频率 f。如果不存在这样的频率,则返回 -1
示例1

输入

888

输出

788

备注:
本题由牛友@Charles 整理上传
数位DP
import java.util.*;
import java.io.*;

// 构造各位递增的数字, 不超过Fmax, 检查各位和质数
// 数位DP:简单应用, 当然普通回溯也行
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[] nums = br.readLine().toCharArray();
        sieve();
        System.out.println(dfs(0, 0, 0, 0, true, nums));
    }

    // 数位DP
    static long dfs(long x, int sum, int pre, int i, boolean isLimit, char[] nums) {
        if (i == nums.length) {
            return prime[sum] ? x : -1;
        }

        long res = -1;
        int upper = isLimit ? nums[i] - '0' : 9;
        for (int k = pre; k <= upper; k++) {
            res = Math.max(res, dfs(x * 10 + k, sum + k, k, i + 1, isLimit && k == upper, nums));
        }
        return res;
    }

    // 质数筛选
    static final boolean[] prime = new boolean[163];
    static void sieve() {
        Arrays.fill(prime, true);
        prime[0] = prime[1] = false;
        for (int i = 2; i <= 13; i++) {
            if (prime[i]) {
                for (int j = i + i; j <= 162; j += i) {
                    prime[j] = false;
                }
            }
        }
    }
}


发表于 2025-10-11 20:49:54 回复(0)