【笔试刷题】小米-2026.03.14-第二套-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

小米-2026.03.14-第二套

小米-2026.03.14-第二套

这套题的梯度很顺。第一题是实现型热身,关键在于把比较规则一层不漏地写对;第二题才是真正的分水岭,必须先把错误题意修正成和样例一致的版本,再去做区间 DP;第三题则是经典贪心模型,能不能一眼认出“截止日排序 + 最小堆”基本决定了写题速度。

题目一:定制选品单

题面看起来只是重新排商品顺序,但真正的排序键不是固定的,而是顾客临时给出的一组维度优先级。因为 很小,直接按顾客顺序做多关键字比较就够了,别把矩阵读反就行。

难度:简单

题目二:并炉品阶

这题最麻烦的不是实现,而是原始题面规则和样例互相矛盾。正式版必须按样例修正成“若 则合成后是 ,否则是 ”,之后用区间 DP 维护每一段能炼出的所有品阶。

难度:中等

题目三:奖章作业表

本质是单位时长任务选择问题。把作业按截止日排序,堆里始终只保留当前能按时做完的最高收益集合;一旦数量超过当前截止日,就删掉收益最小的那份作业。

难度:中等

定制选品单

问题描述

小基 正在为一位顾客整理门店首页的推荐顺序。

店里共有 件商品,每件商品都有 个评价维度。顾客不会直接给出一个总分,而是会给出一个长度为 的排列 ,表示他看重这些维度的先后顺序。

比较两件商品时,规则如下:

  • 先比较它们在维度 上的分数,分数更高的排在前面。
  • 如果这一维相同,就继续比较维度
  • 按同样方式一路比较到维度

已知任意两件商品在全部 个维度上的分数不会完全一样。请输出按顾客偏好从高到低排好序后的商品编号。

输入格式

第一行输入两个整数 ,表示商品数量和评价维度数量。

第二行输入 个整数 ,它们是 的一个排列,表示顾客给出的维度优先级。

接下来输入一个 的分数矩阵。

  • 行第 列的整数 ,表示商品 在第 个维度上的分数。

输出格式

输出一行 个整数,表示按顾客偏好从高到低排序后的商品编号。

样例输入

5 3
1 3 2
4 4 3 4 3
5 2 4 4 4
3 5 2 3 3

样例输出

2 1 4 5 3

样例说明

样例 解释说明
样例 1 顾客先看第 维,再看第 维,最后看第 维。商品 和商品 在第一维同分,但商品 的第三维更高,所以排在最前。商品 与商品 的前两层比较仍然相同,最后由第二维分出先后,因此最终顺序是 2 1 4 5 3

数据范围

  • 的一个排列
  • 保证不存在两件商品在全部维度上的分数完全相同

题解

这题没有隐藏做法,本质就是把“顾客给出的维度顺序”变成真正的排序键。

每件商品都对应一个长度为 的分数向量,但比较时不能按维度编号 直接看,而是必须严格按照顾客给出的顺序 去逐项比较。

因为 ,一次比较最多只会看 个维度,所以直接排序就足够了:

  1. 先读入顾客给出的维度顺序。
  2. 再读入分数矩阵,保留“第几维、哪件商品”的分数。
  3. 排序时枚举顾客给出的维度顺序,找到第一处不同分数,分高的商品排前面。

题目保证不存在两个商品在全部维度上完全相同,所以比较过程一定能在某一维分出先后。

时间复杂度是 。这里的 很小,可以直接看成常数;空间复杂度是 ,用于存储分数矩阵。

参考代码

  • Python
import sys

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


def solve() -> None:
    n, k = map(int, input().split())
    ords = [int(x) - 1 for x in input().split()]
    sc = [list(map(int, input().split())) for _ in range(k)]

    ids = list(range(n))

    def key(i: int):
        # 直接把顾客关心的分数顺序拼成排序键。
        return tuple(-sc[d][i] for d in ords)

    ids.sort(key=key)
    print(*[i + 1 for i in ids])


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

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

    int n, k;
    cin >> n >> k;

    vector<int> ord(k);
    for (int i = 0; i < k; ++i) {
        cin >> ord[i];
        --ord[i];
    }

    vector<vector<int>> sc(k, vector<int>(n));
    for (int i = 0; i < k; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> sc[i][j];
        }
    }

    vector<int> ids(n);
    iota(ids.begin(), ids.end(), 0);

    sort(ids.begin(), ids.end(), [&](int x, int y) {
        // 按顾客给出的维度顺序依次比较。
        for (int d : ord) {
            if (sc[d][x] != sc[d][y]) {
                return sc[d][x] > sc[d][y];
            }
        }
        return x < y;
    });

    for (int i = 0; i < n; ++i) {
        if (i) {
            cout << ' ';
        }
        cout << ids[i] + 1;
    }
    cout << '\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++];
        }

        int nextInt() throws IOException {
            int c;
            do {
                c = read();
            } while (c <= 32 && c != -1);

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

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

    public static void main(String[] args) throws Exception {
        FastScanner fs = new FastScanner();
        int n = fs.nextInt();
        int k = fs.nextInt();

        int[] ord = new int[k];
        for (int i = 0; i < k; i++) {
            ord[i] = fs.nextInt() - 1;
        }

        int[][] sc = new int[k][n];
        for (int i = 0; i < k; i++) {
            for (int j = 0; j < n; j++) {
                sc[i][j] = fs.nextInt();
            }
        }

        Integer[] ids = new Integer[n];
        for (int i = 0; i < n; i++) {
            ids[i] = i;
        }

        Arrays.sort(ids, (x, y) -> {
            // 按顾客给出的维度优先级逐项比较。
            for (int d : ord) {
                if (sc[d][x] != sc[d][y]) {
                    return Integer.compare(sc[d][y], sc[d][x]);
                }
            }
            return Integer.compare(x, y);
        });

        StringBuilder out = new StringBuilder();
        for (int i = 0; i < n; i++) {
            if (i > 0) {
                out.append(' ');
            }
            out.append(ids[i] + 1);
        }
        out.append('\n');
        System.out.print(out);
    }
}

并炉品阶

问题描述

小柯正在整理一排待入炉的药胚。第 枚药胚的当前品阶是

每次操作只能选择两个相邻药胚合并。设它们当前品阶分别为 ,那么新药胚的品阶按下面的正式规则计算:

  • 如果 ,合并结果是
  • 否则,合并结果是

合并后,新药胚会留在原来的位置,整排药胚长度减一。不断操作,直到整排只剩下一枚药胚为止。

请计算:

  1. 最终药胚可能达到的最高品阶。
  2. 最终药胚可能出现的不同品阶数量。

输入格式

第一行输入两个正整数

第二行输入 个正整数 ,表示初始药胚的品阶。

输出格式

输出一行两个整数,分别表示:

  • 最终药胚可能达到的最高品阶。
  • 最终药胚可能出现的不同品阶数量。

样例输入

6 2
2 1 5 1 1 2

样例输出

7 3

样例说明

样例 解释说明
样例 1 合并顺序不同,最终品阶会不同。按某种顺序可以做到最高品阶 ;把所有合法合并顺序考虑完,最终一共会出现 种不同品阶,所以输出 7 3

数据范围

题解

这题最重要的一步,是把正式规则固定成题面现在这版:

  • ,结果是
  • 否则结果是

一旦规则确定,问题就变成了“这一段药胚最后能炼出哪些品阶”。

can[l][r] 表示区间 最终可能得到的所有品阶集合。

1. 状态定义

当区间里只有一枚药胚时,答案只有它自己:

can[i][i] = {a_i}

2. 为什么可以做区间 DP

区间 的最后一次合并,一定是把它拆成两段:

  • 左边是
  • 右边是

左段先独立合成一枚药胚,右段也独立合成一枚药胚,最后再把这两枚合在一起。

所以只要枚举最后一次合并的位置 ,再把 can[l][m]can[m+1][r] 里的所有可能值按规则合并,就能得到 can[l][r]

3. 朴素转移为什么还不够

如果直接枚举左值 、右值 ,一次转移会是 ,其中 是可能的品阶范围。

这里初始品阶不超过 ,每次合并最多加 ,所以最终品阶不会超过 。也就是说

虽然范围不大,但总共有很多个区间和拆分点,直接四重枚举还是显得笨。

4. 把一次集合合并降到

固定较大的那个值为

如果想让结果还是 ,说明较小值必须满足:

因为这时差值严格大于 ,结果不会升阶。

如果想让结果变成 ,说明较小值必须落在:

因为这时差值不超过 ,会升一阶。

于是对左右两个集合各做一遍前缀计数,就能在 时间判断:

  • 另一边是否存在一个值落在
  • 另一边是否存在一个值落在

这样一次“两个集合的合并”就能压到

5. 复杂度

区间 DP 一共有 个“区间 + 拆分点”组合。

每次集合合并是 ,而

所以总时间复杂度是 ,在这题的数据范围里完全可行;空间复杂度是

参考代码

  • Python
import sys

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


def upd(dst, left, right, k, mx):
    # 前缀计数用于判断“某个范围内是否存在可行值”。
    pl = [0] * (mx + 1)
    pr = [0] * (mx + 1)
    for v in range(1, mx + 1):
        pl[v] = pl[v - 1] + left[v]
        pr[v] = pr[v - 1] + right[v]

    for v in range(1, mx + 1):
        if left[v]:
            lo = max(1, v - k)
            # 若右边有值落在 [v-k, v],则能升到 v+1。
            if v + 1 <= mx and pr[v] - pr[lo - 1] > 0:
                dst[v + 1] = 1
            # 若右边有值 <= v-k-1,则结果保持在 v。
            hi = v - k - 1
            if hi >= 1 and pr[hi] > 0:
                dst[v] = 1

        if right[v]:
           

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

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

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

全部评论

相关推荐

一、基础与中间件Q1:线程池的参数一般怎么设置?依据是什么?A:主要看任务是&nbsp;IO&nbsp;密集型还是&nbsp;CPU&nbsp;密集型。IO&nbsp;密集型可设核心线程数为&nbsp;2N(N&nbsp;为&nbsp;CPU&nbsp;核数),CPU&nbsp;密集型设为&nbsp;N+1;最大线程数和队列长度根据业务负载调整,拒绝策略按场景选择(如丢弃或由提交线程执行)。✅&nbsp;思路正确,但未明确“N&nbsp;是&nbsp;CPU&nbsp;核数”,且拒绝策略表述可更规范。Q2:G1&nbsp;垃圾回收器的设计原理是什么?A:先初始标记&nbsp;root&nbsp;对象,再并发标记,然后重新标记修正,最后回收被标记对象。优化可调大堆内存减少&nbsp;GC&nbsp;频率。⚠️&nbsp;流程大致对,但未提&nbsp;G1&nbsp;核心机制(Region&nbsp;分区、Remembered&nbsp;Set、Mixed&nbsp;GC),术语不够准确。Q3:MySQL&nbsp;可重复读(RR)下如何避免幻读?A:InnoDB&nbsp;通过&nbsp;MVCC&nbsp;和加锁机制防止幻读。✅&nbsp;方向正确,但未说明具体是&nbsp;Next-Key&nbsp;Lock(记录锁&nbsp;+&nbsp;间隙锁)&nbsp;实现。Q4:SQL&nbsp;走了索引还是很慢,怎么优化?A:先看执行计划是否真走索引(避免隐式转换、最左匹配失效);若数据量大,考虑分库分表;还可加缓存,用消息队列更新缓存。✅&nbsp;思路完整,覆盖排查&nbsp;→&nbsp;架构&nbsp;→&nbsp;缓存三层优化。Q5:如何保证缓存(Redis)和数据库的一致性?A:更新数据库后删除缓存;读时若缓存为空,再查&nbsp;DB&nbsp;并回填。实习中也用过“写&nbsp;DB&nbsp;后更新缓存”。⚠️&nbsp;未明确推荐方案是&nbsp;“先更新&nbsp;DB,再删缓存”(Cache-Aside&nbsp;模式),后者易引发脏读。Q6:Redis&nbsp;缓存雪崩怎么解决?A:给缓存设置随机过期时间;热点&nbsp;key&nbsp;更新时加锁,只让一个线程重建缓存,其他等待。✅&nbsp;回答清晰,覆盖主流方案(过期打散&nbsp;+&nbsp;互斥重建)。Q7:Kafka&nbsp;如何保证消息不丢失、不重复消费?A:不丢:靠副本机制和磁盘持久化(默认保留&nbsp;7&nbsp;天);不重:业务层做幂等,比如用达人&nbsp;ID&nbsp;去重。✅&nbsp;工程实践优秀,结合&nbsp;Kafka&nbsp;特性与业务兜底。Q8:Spring&nbsp;AOP&nbsp;如何实现方法耗时统计?A:自定义注解,在切面中记录方法执行前后时间,计算差值。✅&nbsp;完全正确,简洁实用。二、项目与实习Q9:请讲一段你实习中做得比较关键的项目。Q10:项目中有用到事务吗?如何保证一致性?三、AI&nbsp;与开放设计Q11:MCP&nbsp;是什么?A:MCP&nbsp;是一种协议,统一封装&nbsp;AI&nbsp;调用外部工具的能力(如查天气),类似&nbsp;USB&nbsp;接口,便于插拔扩展。✅&nbsp;理解准确,类比形象。Q12:如果让你用&nbsp;AI&nbsp;优化教务系统,你会怎么做?A:针对教师排课,AI&nbsp;可自动分析课程依赖关系,生成多套排课方案并给出推荐理由,减轻老师负担。✅&nbsp;抓住核心痛点(排课复杂),有业务思考;可补充更多场景(如智能选课、毕业审核自动化)。四、行为与规划Q13:你未来的职业规划是什么?A:坚定走后端方向,前期深耕业务与技术栈,后期考虑往技术深度或管理发展。✅&nbsp;方向清晰;⚠️&nbsp;可更具体(如“希望深入分布式系统或云原生架构”)。Q14:你有什么想问我们的?A:询问部门具体负责哪个产品(学习通/学工/教务/校园信息化),以及校招流程。✅&nbsp;体现主动性和岗位关注。
查看14道真题和解析
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

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