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

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

小米-2026.03.14

这套题整体不偏,都是典型的“题面平和,但切入点必须找准”的中等题。第一题考的是连通块预处理和四方向去重,第二题则是标准的邻项交换贪心,能不能把排序准则推出来就是分水岭。

题目一:蓄水区扩建方案

表面上像是对每个位置都做一次改造模拟,实际上真正该做的是先把所有已有蓄水块统一编号。难点不在 BFS 本身,而在于枚举四个方向时要记得去重,否则同一连通块会被重复累加。

难度:中等

题目二:单窗业务排程

这题最关键的是别被“总时间最小”吓住,核心只是一条邻项交换结论。把两个人的相对顺序比较清楚以后,排序规则自然就出来了;后面的递推式只是顺着题意把总耗时滚动更新。

难度:中等

01. 蓄水区扩建方案

问题描述

小基 正在整理一块实验用地的蓄水布局。整块区域被划分成一个 的网格,每个格子只有两种状态:

  • x 表示硬化地面,当前不能蓄水。
  • o 表示蓄水单元,水可以在相邻蓄水单元之间流动。

如果两个蓄水单元可以通过上下左右移动互相到达,就认为它们属于同一个连通蓄水区。

现在允许进行一次改造。对于每个格子:

  • 如果该格子原本就是 o,输出 0
  • 如果该格子原本是 x,假设把它改造成 o,需要输出改造后包含该格子的连通蓄水区大小。

请按网格形式输出每个位置对应的结果。

输入格式

第一行输入两个正整数 ,表示网格的行数和列数。

接下来输入 行,每行是一个长度为 的字符串,只包含 xo,表示初始布局。

输出格式

输出 行,每行输出 个整数。

  • 对于原本是 o 的格子,输出 0
  • 对于原本是 x 的格子,输出把它改造成 o 后,包含该格子的连通蓄水区大小。

相邻数字之间用一个空格分隔。

样例输入 1

3 3
xoo
oxo
xox

样例输出 1

5 0 0
0 6 0
3 0 5

样例说明 1

左上角位置原本是 x。如果把它改造成 o,它会和右边、下边已经连通的蓄水单元连在一起,形成大小为 的连通蓄水区。

中间位置也是 x。如果把它改造成 o,周围四个方向的蓄水单元都会被连起来,因此答案是

样例输入 2

6 5
ooooo
oxxoo
xxxox
oxxoo
xooxx
ooooo

样例输出 2

0 0 0 0 0
0 12 12 0 0
13 1 12 0 12
0 9 19 0 0
9 0 0 19 19
0 0 0 0 0

样例说明 2

例如第 行第 列原本是 x。如果把它改造成 o,就能把周围几个不同的蓄水区拼接成一个更大的整体,因此对应输出是

数据范围

题解

直接暴力做会很慢。

如果对每一个 x 都重新跑一遍 BFS 或 DFS,去看把它改成 o 以后能连出多大的连通块,那么一次遍历是 ,总复杂度会膨胀到 ,肯定过不去。

这题的关键不是“每个位置单独模拟”,而是先把原图里已经存在的连通块一次性处理完。

第一步:给所有 o 连通块编号

先遍历整张图。

每遇到一个还没有编号的 o,就从这里出发做一次 BFS,把整个连通块染成同一个编号,并顺手统计这个连通块的大小。

处理结束后,会得到两类信息:

  • id[i][j]:位置 属于哪个连通块。
  • siz[k]:编号为 的连通块大小。

这样一来,任何一个 o 属于哪个连通块、这个连通块有多大,都可以 查出来。

第二步:枚举每个 x

对于一个待改造的 x,它变成 o 之后,只可能和上下左右四个方向的连通块连起来。

所以答案就是:

  • 先把自己算进去,初始值为
  • 看四个方向有哪些 o
  • 如果相邻的 o 来自不同编号的连通块,就把这些连通块大小累加进来。

这里要注意去重。

因为同一个连通块可能从两个方向同时挨着当前格子,如果不去重,就会重复加两次。

由于只有四个方向,直接用一个很小的数组或集合去重就够了,代价非常小。

为什么这样做是对的

改造一个 x 以后,新的连通块只会由这几部分组成:

  • 当前这个位置自己。
  • 与它四联通相邻的那些原有 o 连通块。

除此之外,不可能再多出别的部分。

因为连通只能通过上下左右传播,而所有能通过当前格子接上的区域,入口都只能来自四个相邻位置。

所以只要把四个方向涉及到的不同连通块大小全部加起来,得到的就是唯一正确答案。

复杂度分析

设网格大小为

  • 第一次 BFS 染色,每个格子最多进队一次,复杂度是
  • 第二次枚举每个格子时,每个位置只检查四个方向,复杂度也是

总时间复杂度为 ,空间复杂度为

参考代码

  • Python
import sys
from collections import deque

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


def solve() -> None:
    n, m = map(int, input().split())
    g = [list(input()) for _ in range(n)]

    # comp[i][j] 记录当前位置属于哪个蓄水连通块,-1 表示尚未编号。
    comp = [[-1] * m for _ in range(n)]
    siz = []
    dirs = [(-1, 0), (1, 0), (0, -1), (0, 1)]

    def bfs(sr: int, sc: int, idx: int) -> int:
        q = deque([(sr, sc)])
        comp[sr][sc] = idx
        cnt = 0
        while q:
            x, y = q.popleft()
            cnt += 1
            for dx, dy in dirs:
                nx, ny = x + dx, y + dy
                if not (0 <= nx < n and 0 <= ny < m):
                    continue
                if g[nx][ny] != 'o' or comp[nx][ny] != -1:
                    continue
                comp[nx][ny] = idx
                q.append((nx, ny))
        return cnt

    # 先给所有原有的蓄水区编号,并统计每个连通块大小。
    for i in range(n):
        for j in range(m):
            if g[i][j] == 'o' and comp[i][j] == -1:
                idx = len(siz)
                siz.append(bfs(i, j, idx))

    ans = [[0] * m for _ in range(n)]
    for i in range(n):
        for j in range(m):
            if g[i][j] == 'o':
                continue

            cur = 1
            used = set()
            # 当前格子变成 o 之后,只会连接四个方向的不同连通块。
            for dx, dy in dirs:
                ni, nj = i + dx, j + dy
                if not (0 <= ni < n and 0 <= nj < m):
                    continue
                if g[ni][nj] != 'o':
                    continue
                idx = comp[ni][nj]
                if idx in used:
                    continue
                used.add(idx)
                cur += siz[idx]
            ans[i][j] = cur

    for row in ans:
        print(*row)


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

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

    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    for (int i = 0; i < n; ++i) {
        cin >> g[i];
    }

    vector<vector<int>> comp(n, vector<int>(m, -1));
    vector<int> siz;
    const int dx[4] = {-1, 1, 0, 0};
    const int dy[4] = {0, 0, -1, 1};

    auto bfs = [&](int sx, int sy, int id) {
        queue<pair<int, int>> q;
        q.push({sx, sy});
        comp[sx][sy] = id;
        int cnt = 0;

        while (!q.empty()) {
            auto [x, y] = q.front();
            q.pop();
            ++cnt;

            for (int k = 0; k < 4; ++k) {
                int nx = x + dx[k];
                int ny = y + dy[k];
                if (nx < 0 || nx >= n || ny < 0 || ny >= m) {
                    continue;
                }
                if (g[nx][ny] != 'o' || comp[nx][ny] != -1) {
                    continue;
                }
                comp[nx][ny] = id;
                q.push({nx, ny});
            }
        }
        return cnt;
    };

    // 先把所有已有的蓄水区染色。
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (g[i][j] == 'o' && comp[i][j] == -1) {
                int id = (int)siz.size();
                siz.push_back(bfs(i, j, id));
            }
        }
    }

    vector<vector<int>> ans(n, vector<int>(m, 0));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (g[i][j] == 'o') {
                continue;
            }

            int cur = 1;
            int used[4];
            int top = 0;

            // 只统计四个方向出现的不同连通块。
            for (int k = 0; k < 4; ++k) {
                int ni = i + dx[k];
                int nj = j + dy[k];
                if (ni < 0 || ni >= n || nj < 0 || nj >= m) {
                    continue;
                }
                if (g[ni][nj] != 'o') {
                    continue;
                }

                int id = comp[ni][nj];
                bool ok = true;
                for (int t = 0; t < top; ++t) {
                    if (used[t] == id) {
                        ok = false;
                        break;
                    }
                }
                if (!ok) {
                    continue;
                }
                used[top++] = id;
                cur += siz[id];
 

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

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

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

全部评论

相关推荐

昨天 10:21
门头沟学院 Java
刷到&nbsp;AI&nbsp;岗位的春招数据,整个人都焦虑到失眠。2026&nbsp;年春招&nbsp;AI&nbsp;岗位量同比暴涨&nbsp;12&nbsp;倍,平均月薪直接冲到&nbsp;60738&nbsp;元,人才供需比&nbsp;0.97,相当于岗位比人还多,而我所在的传统后端开发岗,入门岗位量跌了快&nbsp;30%,几百人抢一个&nbsp;HC。身边的同事和同学,一半在学大模型相关技术,一半已经投了&nbsp;AI&nbsp;岗的简历,连牛客上的面经,十篇有八篇都是&nbsp;AI&nbsp;算法、大模型开发。每天坐在工位上,看着自己写了好几年的&nbsp;CRUD,满脑子都是:再不转&nbsp;AI,是不是就要被淘汰了?可真的想转的时候,又陷入了无尽的内耗。看高薪的大模型算法岗,基本都要求硕士以上学历,还要扎实的数学功底和算法基础,我一个双非本科,只会写业务代码,连门槛都摸不到;看相对友好的&nbsp;AI&nbsp;应用开发岗,也要懂&nbsp;RAG、智能体开发、LangChain,一堆新东西要学,一边要应付日常加班,一边挤时间啃新技术,学了半个月,还是连门都没入。更怕的是,等我费劲巴拉学完,风口又过去了,传统开发的手艺丢了,AI&nbsp;岗也没挤进去,最后两头空。一边是肉眼可见的行业趋势,一边是高不可攀的转型门槛;一边是传统岗位越来越卷,一边是&nbsp;AI&nbsp;赛道看着香却吃不到。每天都在&nbsp;“必须转&nbsp;AI”&nbsp;和&nbsp;“我根本转不过去”&nbsp;之间反复横跳,快被这种焦虑磨疯了。
AI岗位暴涨12倍,你会...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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