【笔试刷题】京东-2026.04.04-研发岗-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

京东-2026.04.04-研发岗

这套题的分工很清楚:第一题是在乱序快照里反推二维等差偏移,重点是把“矩阵里的所有可能值”转成可排序的偏移量集合;第二题则是标准的区间覆盖型 DP,和 Strange Printer 是同一个模型。

题目一:矩阵快照校验

关键不在于枚举起点,而在于先把所有位置相对左上角的偏移量列出来。最小元素一定对应左上角,再把两边排序后一一核对即可。

难度:中等

题目二:区间批量标注

这题允许后续覆盖前面的颜色,本质就是“最少几次区间打印”。先压缩连续相同段,再做区间 DP,复杂度是

难度:中等偏上

1. 矩阵快照校验

问题描述

小基 在核对一张按固定规则生成的数值表。

这张表的大小为 。她先选定三个整数 ,然后按照下面的规则填写整张表:

  • 向下走一格时,数值增加 ,也就是
  • 向右走一格时,数值增加 ,也就是

例如,当 时,这张表是:

1 4 7
3 6 9
5 8 11

现在,小基 只记得 的值。她另外找到一个长度为 的数组 ,其中保存了这张表中的全部元素,只是顺序已经被打乱。

请你判断:是否存在某个满足规则的表,使得数组 恰好由这张表的全部元素组成。

可以证明,对于任意给定的 ,满足规则的表都是唯一的。

输入格式

单个测试文件包含多组数据。

第一行输入一个整数 ,表示测试数据组数。

对于每组数据:

  • 第一行输入三个整数
  • 第二行输入 个整数,表示被打乱后的全部元素。

输出格式

对于每组数据,如果可以构造出满足要求的数值表,输出 YES;否则输出 NO

样例输入

5
3 2 3
3 9 6 5 7 1 10 4 8
3 2 3
3 9 6 5 7 1 11 4 8
2 100 100
400 300 400 500
3 2 3
3 9 6 5 1 1 11 4 8
4 4 4
15 27 7 19 23 23 11 15 7 3 19 23 11 15 11 15

样例输出

NO
YES
YES
NO
NO

数据范围

  • 保证每组数据都给出恰好 个整数。
  • 保证单个测试文件中所有数据的 之和不超过
样例 解释说明
样例1 第一组里应当出现的 被替换成了 ,因此无法匹配出合法矩阵。
样例2 第二组正好对应左上角为 的那张 数值表,所以答案是 YES
样例3 时, 的表中本来就会出现两个 ,因此第三组依然合法。

题解

关键转化

如果左上角的值是 ,那么位置 上的元素一定是:

也就是说,整张表的所有元素都可以看成:

  • 一个固定起点
  • 再加上一组只由 决定的偏移量

于是题目变成了:

  1. 先把所有偏移量 列出来。
  2. 再判断数组 是否能写成“某个起点 + 这组偏移量”。

为什么最小值就能确定左上角

因为题目保证 ,所以偏移量的最小值一定是 ,对应左上角位置。

因此,把数组 排序后,最小元素一定就是候选的
接下来只需要把:

  • 所有偏移量排序
  • 数组 排序

然后逐个比较:

只要有一个位置不相等,就说明这组数据不可能来自某张合法矩阵。

做法

对每组数据执行下面几步:

  1. 读入全部 个数。
  2. 枚举所有位置,生成 个偏移量。
  3. 分别排序偏移量数组和输入数组。
  4. 令最小输入值作为候选左上角。
  5. 逐个检查两边是否完全对应。

复杂度分析

设当前测试的矩阵大小为

  • 生成偏移量:
  • 两次排序:
  • 逐项比较:

所以单组数据的总时间复杂度是 ,空间复杂度是

参考代码

  • Python
import sys

input = lambda: sys.stdin.readline().strip()


def solve() -> None:
    t = int(input())
    ans = []

    for _ in range(t):
        n, c, d = map(int, input().split())

        need = n * n
        b = []
        while len(b) < need:
            b.extend(map(int, input().split()))

        off = []
        for i in range(n):
            base = i * c
            for j in range(n):
                off.append(base + j * d)

        b.sort()
        off.sort()
        a00 = b[0]

        ok = True
        for x, y in zip(b, off):
            if x != a00 + y:
                ok = False
                break

        ans.append("YES" if ok else "NO")

    print("\n".join(ans))


if __name__ == "__main__":
    solve()
  • Cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;
    while (t--) {
        int n;
        long long c, d;
        cin >> n >> c >> d;

        int m = n * n;
        vector<long long> b(m), off;
        off.reserve(m);

        for (int i = 0; i < m; ++i) {
            cin >> b[i];
        }

        for (int i = 0; i < n; ++i) {
            long long base = 1LL * i * c;
            for (int j = 0; j < n; ++j) {
                off.push_back(base + 1LL * j * d);
            }
        }

        sort(b.begin(), b.end());
        sort(off.begin(), off.end());

        long long a00 = b[0];
        bool ok = true;
        for (int i = 0; i < m; ++i) {
            if (b[i] != a00 + off[i]) {
                ok = false;
                break;
            }
        }

        cout << (ok ? "YES" : "NO") << '\n';
    }
    return 0;
}
  • Java
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Arrays;

public class Main {
    static class FastScanner {
        private final BufferedInputStream in = new BufferedInputStream(System.in);
        private final byte[] buf = new byte[1 << 16];
        private int len = 0;
        private int ptr = 0;

        private int read() throws IOException {
            if (ptr >= len) {
                len = in.read(buf);
                ptr = 0;
                if (len <= 0) {
                    return -1;
                }
            }
            return buf[ptr++];
        }

        long nextLong() throws IOException {
            int c;
            do {
                c = read();
            } while (c <= ' ' && c != -1);

            long sign = 1;
            if (c == '-') {
                sign = -1;
                c = read();
            }

            long val = 0;
            while (c > ' ') {
                val = val * 10 + c - '0';
                c = read();
            }
            return val * sign;
        }
    }

    public static void main(String[] arg

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

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

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

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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