【秋招笔试】2025.08.23京东秋招笔试改编题

✅ 秋招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题
  • 对照解析查漏补缺

🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力

🌸 目前本专栏已经上线140+套真题改编解析,后续会持续更新的

春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗

题目一:小兰的菜谱安排

1️⃣:特殊情况处理,当k=0时直接快速幂计算m^n

2️⃣:动态规划+前缀和优化,状态转移考虑相邻约束条件

难度:中等

这道题目的关键在于理解相邻元素差值约束的动态规划问题。当k=0时为无约束情况,直接用快速幂计算。当k>0时需要用DP,通过前缀和优化区间求和,实现O(nm)时间复杂度的高效解法。

题目二:小毛的机器人导航

1️⃣:状态扩展BFS,将移动方向作为状态维度

2️⃣:三元组状态(x,y,dir)表示位置和上一步移动方向

3️⃣:根据移动方向约束进行状态转移

难度:中等

这道题目需要理解带有特殊约束的最短路径问题。关键在于将"上一步移动方向"纳入状态,使用三维BFS来处理方向交替的约束条件。通过合理的状态设计和转移,可以在O(nm)时间内求出最短路径。

01. 小兰的菜谱安排

问题描述

小兰是一名美食博主,她每天都要更新自己的料理日记。为了让观众们不觉得单调,小兰决定制定一个 天的菜谱计划,确保连续两天制作的菜品风格不能太相似。

小兰总共掌握 种不同的菜品,每种菜品都有一个独特的风味编号(从 )。她认为只有当两种菜品的风味编号相差至少 时,它们的口味才算是明显不同的。

现在小兰想知道:在满足相邻两天菜品风味差异至少为 的条件下,一共有多少种不同的 天菜谱安排方案?

由于方案数可能很大,请将结果对 取模。

输入格式

输入一行包含三个正整数 ,分别表示计划天数、菜品总数和最小风味差异值。

输出格式

输出一行,包含一个整数,表示合法的菜谱安排方案数,结果对 取模。

样例输入

3 4 2

样例输出

10

数据范围

样例 解释说明
样例1 3天计划,4种菜品,相邻菜品编号差至少为2,共有10种合法安排方案

题解

这道题本质上是一个动态规划问题,需要计算满足相邻元素差值约束的序列数量。

首先分析问题的特殊情况:当 时,相邻菜品没有任何限制,每天都可以选择任意菜品,答案就是 ,可以用快速幂快速计算。

时,就需要考虑相邻约束了。可以用动态规划来解决:

定义状态 dp[i][j] 表示前 天,第 天选择菜品 的方案数。

状态转移时,第 天选择菜品 ,那么第 天的菜品 必须满足 ,也就是 或者

因此转移方程为:

为了快速计算这两个区间和,可以维护前缀和数组。对于第 层的状态,计算前缀和 pre[x] = dp[i][1] + dp[i][2] + ... + dp[i][x],这样就能用 的时间计算任意区间和。

算法的时间复杂度是 ,对于 的数据范围完全可以接受。

参考代码

  • Python
import sys
input = lambda: sys.stdin.readline().strip()

MOD = 998244353

def pow_mod(a, e):
    # 快速幂函数,计算 a^e % MOD
    res = 1
    while e > 0:
        if e & 1:
            res = res * a % MOD
        a = a * a % MOD
        e >>= 1
    return res

def add_mod(a, b):
    # 模意义下的加法
    return (a + b) % MOD

def sub_mod(a, b):
    # 模意义下的减法
    return (a - b + MOD) % MOD

n, m, k = map(int, input().split())

# 特殊情况:无约束条件
if k == 0:
    print(pow_mod(m, n))
else:
    # 动态规划求解
    dp = [1] * (m + 1)  # dp[i] 表示选择菜品i的方案数
    
    for day in range(2, n + 1):
        # 计算前缀和
        pre = [0] * (m + 1)
        for i in range(1, m + 1):
            pre[i] = add_mod(pre[i-1], dp[i])
        
        total = pre[m]  # 所有方案数的总和
        new_dp = [0] * (m + 1)
        
        for u in range(1, m + 1):
            # 计算 v <= u-k 的方案数
            left_sum = pre[u-k] if u-k >= 1 else 0
            # 计算 v >= u+k 的方案数  
            right_sum = sub_mod(total, pre[u+k-1]) if u+k <= m else 0
            new_dp[u] = add_mod(left_sum, right_sum)
        
        dp = new_dp
    
    # 计算最终答案
    ans = 0
    for i in range(1, m + 1):
        ans = add_mod(ans, dp[i])
    
    print(ans)
  • Cpp
#include <bits/stdc++.h>
using namespace std;

const int MOD = 998244353;

// 快速幂函数
long long pow_mod(long long a, long long e) {
    long long res = 1;
    while (e > 0) {
        if (e & 1) res = res * a % MOD;
        a = a * a % MOD;
        e >>= 1;
    }
    return res;
}

// 模意义下的加法
inline int add_mod(int a, int b) {
    return (a + b) >= MOD ? (a + b - MOD) : (a + b);
}

// 模意义下的减法
inline int sub_mod(int a, int b) {
    return (a - b) < 0 ? (a - b + MOD) : (a - b);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m, k;
    cin >> n >> m >> k;
    
    // 特殊情况处理
    if (k == 0) {
        cout << pow_mod(m, n) << "\n";
        return 0;
    }
    
    // 初始化dp数组,第一天每种菜品都可以选
    vector<int> dp(m + 1, 1);
    
    for (int day = 2; day <= n; ++day) {
        // 计算前缀和数组
        vector<int> pre(m + 1, 0);
        for (int i = 1; i <= m; ++i) {
            pre[i] = add_mod(pre[i-1], dp[i]);
        }
        
        int total = pre[m];
        vector<int> new_dp(m + 1, 0);
        
        for (int u = 1; u <= m; ++u) {
            // 计算满足条件的方案数
            int left_sum = (u - k >= 1) ? pre[u - k] : 0;
            int right_sum = (u + k <= m) ? sub_mod(total, pre[u + k - 1]) : 0;
            new_dp[u] = add_mod(left_sum, right_sum);
        }
        
        dp = move(new_dp);
    }
    
    // 统计最终答案
    int ans = 0;
    for (int i = 1; i <= m; ++i) {
        ans = add_mod(ans, dp[i]);
    }
    
    cout << ans << "\n";
    return 0;
}
  • Java
import java.util.*;
import java.io.*;

public class Main {
    static final int MOD = 998244353;
    
    // 快速幂函数
    static long powMod(long a, long e) {
        long res = 1;
        while (e > 0) {
            if ((e & 1) == 1) res = res * a % MOD;
            a = a * a % MOD;
            e >>= 1;
        }
        return res;
    }
    
    // 模意义下的加法
    static int addMod(int a, int b) {
        return (a + b) >= MOD ? (a + b - MOD) : (a + b);
    }
    
    // 模意义下的减法
    static int subMod(int a, int b) {
        return (a - b) < 0 ? (a - b + MOD) : (a - b);
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        
        // 特殊情况:无约束
        if (k == 0) {
            System.out.println(powMod(m, n));
            return;
        }
        
        // DP求解
        int[] dp = new int[m + 1];
        Arrays.fill(dp, 1, m + 1, 1);  // 第一天每种菜都可选
        
        for (int day = 2; day <= n; ++day) {
            // 计算前缀和
            int[] prefSum = new int[m + 1];
            for (int i = 1; i <= m; ++i) {
                prefSum[i] = addMod(prefSum[i-1], dp[i]);
            }
            
            int totalSum = prefSum[m];
            int[] newDp = new int[m + 1];
            
  

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务