跳转至

帆软

帆软

100分钟:单选5道+不定项选择6道+填空2道+编程题2道

第一道:回文串

题目描述

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

回文字符定义为:首尾对称的字符,例如"a","baab","aba"。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例 1: 输入:s = "bbbab" 输出:4

解释:一个可能的最长回文子序列为 "bbbb" 。

示例 2: 输入:s = "cbacbd" 输出:3

解释:一个可能的最长回文子序列为 "bab" 。

代码实现

import java.util.Scanner;

public class Main {
    public static int longestPalindromeSubseq(String s) {
        int n = s.length();
        // dp[i][j] 表示 s[i..j] 中最长回文子序列的长度
        int[][] dp = new int[n][n];

        // 从字符串的末尾开始遍历
        for (int i = n - 1; i >= 0; i--) {
            dp[i][i] = 1; // 单个字符的回文子序列长度为1
            for (int j = i + 1; j < n; j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    // 如果字符相等,长度加2
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    // 如果字符不相等,取两种情况的最大值
                    dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
        // 返回整个字符串的最长回文子序列长度
        return dp[0][n - 1];
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取输入字符串
        String s = scanner.nextLine();
        scanner.close();
        // 计算最长回文子序列的长度
        int result = longestPalindromeSubseq(s);
        // 输出结果
        System.out.println(result);
    }
}

第二题

题目描述

输入一个正整数N (1 ≤ N ≤ 44,777,444),请你返回 k 个正整数 \(a_1, a_2, a_3..., a_k\),满足 \({a_1}^3+a_2^3+a_3^3+...+a_k^3 = N\),同时保证 k 的值最小。

返回长度为k的数组,并降序排序

示例: 输入:42 输出:2 2 2 2 2 1 1

代码

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取输入的正整数 N
        int N = scanner.nextInt();
        scanner.close();

        // 预处理:生成所有不超过 N 的立方数
        List<Integer> cubes = new ArrayList<>();
        int maxCubeRoot = (int) Math.cbrt(N);
        for (int i = 1; i <= maxCubeRoot; i++) {
            cubes.add(i * i * i);
        }

        // 使用 BFS 或 A* 搜索最小的 k
        List<Integer> result = findMinCubes(N, cubes);

        // 将结果降序排序并输出
        Collections.sort(result, Collections.reverseOrder());
        for (int i = 0; i < result.size(); i++) {
            System.out.print(result.get(i));
            if (i != result.size() - 1) {
                System.out.print(" ");
            }
        }
    }

    private static List<Integer> findMinCubes(int N, List<Integer> cubes) {
        // 使用 HashMap 存储每个状态的最小 k 值
        Map<Integer, List<Integer>> memo = new HashMap<>();
        Queue<Node> queue = new LinkedList<>();
        queue.offer(new Node(N, new ArrayList<>()));

        while (!queue.isEmpty()) {
            Node current = queue.poll();
            int remainder = current.remainder;
            List<Integer> path = current.path;

            // 如果已经计算过且当前路径长度不小于已存在的路径长度,跳过
            if (memo.containsKey(remainder) && memo.get(remainder).size() <= path.size()) {
                continue;
            }

            memo.put(remainder, path);

            if (remainder == 0) {
                return path;
            }

            // 尝试所有可能的立方数
            for (int i = cubes.size() - 1; i >= 0; i--) {
                int cube = cubes.get(i);
                if (cube <= remainder) {
                    List<Integer> newPath = new ArrayList<>(path);
                    newPath.add((int) Math.cbrt(cube));
                    queue.offer(new Node(remainder - cube, newPath));
                }
            }
        }

        // 理论上不会到这里,保证一定有解
        return new ArrayList<>();
    }

    static class Node {
        int remainder;
        List<Integer> path;

        Node(int remainder, List<Integer> path) {
            this.remainder = remainder;
            this.path = path;
        }
    }
}