【笔试刷题】虾皮-2026.03.28-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

虾皮-2026.03.28

这套题的梯度比较顺手。第 1 题是标准的网格连通性统计,抓住“答案 = 总格子数 - 可达格子数”就能直接做;第 2 题切到高精度模拟,核心是把十进制数按位存下来反复乘 2;第 3 题则回到经典位运算,利用整体异或和最低位 1 把两个只出现一次的数拆开。

题目一:迷宫封锁区统计

真正要找的不是“哪些格子不可达”,而是“起点到底能摸到哪些格子”。从左上角做一遍 BFS,最后用 减掉可达格子数,墙和被堵住的空地会一起被自然计入答案。

难度:Low

题目二:二进制扩容后的十进制串

这题本质上就是高精度乘 2。用数组倒着存十进制位,从低位往高位处理进位,重复做 轮,最后倒序输出即可。

难度:Mid

题目三:仓库复核里的两张异常标签

整段数组异或后,留下的是两个目标值的异或结果。再取其中任意一个为 1 的二进制位分组,成对元素会继续抵消,两组里各自剩下一个答案。

难度:Mid

1. 迷宫封锁区统计

问题描述

小基 在调试一张 的迷宫地图。

地图中的每个格子只有两种状态:

  • 0 表示可以通行;
  • 1 表示本身就是障碍,无法进入。

玩家从左上角坐标 出发,只能沿着上、下、左、右四个方向移动。

现在需要统计整张地图里“无法从起点到达”的格子总数。这里的无法到达包含两类:

  • 原本就是障碍的格子;
  • 虽然值是 0,但因为被障碍隔开,无法从起点走到的格子。

请你输出这样的格子数量。

输入格式

第一行输入一个整数 ,表示地图的边长。

接下来输入 行,每行有 个整数 ,表示迷宫地图。

保证:

  • 输入矩阵一定是
  • 起点 一定是 0

输出格式

输出一个整数,表示不可到达的格子总数。

样例输入 1

4
0 1 1 0
1 0 0 0
0 1 0 1
0 1 1 0

样例输出 1

15

样例输入 2

4
0 0 0 0
1 0 0 1
0 0 1 0
0 0 0 1

样例输出 2

5

样例输入 3

4
0 0 0 0
0 0 1 0
0 0 1 0
1 0 0 0

样例输出 3

3

数据范围

  • 地图元素只会是 01
  • 保证
样例 解释说明
样例1 起点周围被快速封死,只有左上角自己可达,所以答案是
样例2 除了 4 个障碍外,右下角那个 0 也被隔开,因此总共有 5 个格子不可达。
样例3 只有 3 个格子无法从起点走到,其中包含障碍和被挡住的空地。

题解

这题最关键的观察只有一句:

不可到达的格子数 = 全部格子数 - 从起点能够走到的格子数。

因为题目把两类格子都算进答案里:

  • 原生的障碍 1 本来就走不到;
  • 被围住的空地 0 也走不到。

所以我们根本不需要分别统计这两类,只要把“真正可达的格子”找出来,剩下的自然全都是答案。

做法就是从起点 开始跑一次 BFS:

  1. 只有值为 0 的格子才能入队。
  2. 每次从队首取出一个格子,尝试往四个方向扩展。
  3. 邻居如果在边界内、值仍然是 0、并且之前没有访问过,就把它加入队列。
  4. BFS 结束后,reachable 记录的就是所有可达空地数量。

最后答案就是:

为什么这样是对的?

  • BFS 会完整找出与起点属于同一个连通块的所有空地。
  • 所有没有被 BFS 访问到的格子,要么本身是 1,要么虽然是 0 但不和起点连通。
  • 这两类正好就是题目要求统计的全部不可达格子。

时间复杂度是 ,因为每个格子最多进队一次。空间复杂度也是 ,用于访问标记和队列。

参考代码

  • Python
import sys
from collections import deque

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


def solve():
    n = int(input())
    grid = [list(map(int, input().split())) for _ in range(n)]

    q = deque([(0, 0)])
    vis = [[False] * n for _ in range(n)]
    vis[0][0] = True
    reachable = 0

    dirs = ((1, 0), (-1, 0), (0, 1), (0, -1))

    while q:
        x, y = q.popleft()
        reachable += 1

        for dx, dy in dirs:
            nx = x + dx
            ny = y + dy
            # 只把边界内、可通行、且没访问过的格子加入队列。
            if 0 <= nx < n and 0 <= ny < n and grid[nx][ny] == 0 and not vis[nx][ny]:
                vis[nx][ny] = True
                q.append((nx, ny))

    print(n * n - reachable)


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

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

    int n;
    cin >> n;

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

    queue<pair<int, int>> q;
    vector<vector<int>> vis(n, vector<int>(n, 0));
    q.push({0, 0});
    vis[0][0] = 1;
    int reachable = 0;

    const int dx[4] = {1, -1, 0, 0};
    const int dy[4] = {0, 0, 1, -1};

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

        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 >= n) {
                continue;
            }
            if (grid[nx][ny] != 0 || vis[nx][ny]) {
                continue;
            }
            vis[nx][ny] = 1;
            q.push({nx, ny});
        }
    }

    cout << n * n - reachable << '\n';
    return 0;
}
  • Java
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner fs = new FastScanner(System.in);
        int n = fs.nextInt();
        int[][] grid = new int[n][n];

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

        ArrayDeque<int[]> q = new ArrayDeque<>();
        boolean[][] vis = new boolean[n][n];
        q.offer(new int[]{0, 0});
        vis[0][0] = true;
        int reachable = 0;

        int[] dx = {1, -1, 0, 0};
        int[] dy = {0, 0, 1, -1};

        while (!q.isEmpty()) {
            int[] cur = q.poll();
            int x = cur[0];
            int y = cur[1];
            reachable++;

            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 >= n) {
                    continue;
                }
                if (grid[nx][ny] != 0 || vis[nx][ny]) {
                    continue;
                }
                vis[nx][ny] = true;
                q.offer(new int[]{nx, ny});
            }
        }

        System.out.println(n * n - reachable);
    }

    static class FastScanner {
        private final InputStream in;
        private final byte[] buffer = new byte[1 << 16];
        private int len = 0;
        private int ptr = 0;

        FastScanner(InputStream is) {
            in = is;
        }

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

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

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

            int val = 0;
            while (c > ' ') {
               

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

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

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

全部评论

相关推荐

不愿透露姓名的神秘牛友
03-23 10:00
小鹏汽车 采购 16.5Kx(13-15) 大专
点赞 评论 收藏
分享
笔试结构5单选+5单选+5多选+3编程1、五个单选(只记得第一个是父母两个孩子,其中一个女生,另一个是男生的概率)这部分应该跟专业知识相关不大,印象里做得挺快的。2、五个单选(DES弱秘钥个数;进程执行过程中移除可执行文件和动态链接库会不会有影响;算法时间复杂度(只有一个简单的你*(n-2)的递归);初始ab值,互相异或操作以后ab的值)3、五个多选,四选三,选不全三分之一分,选错不得分。(Linux&nbsp;S什么&nbsp;V进程之间同步选项是信号量,信号,消息队列,共享内存;Shell一定会执行的命令exec,fork;SMTP协议的内容,问邮件发送的:邮件在邮件服务器之间发送,用户代理发给邮件服务器,服务器发给用户代理,还有一个选项忘记了;TCP连接断开连接的一方状态字段,只记得一个TIME_WAIT)。这部分我不太会,以上写的只是部分选项,不代表正确答案。4、三道编程(其实都挺简单的,但奈何我有点菜,想了挺久):第一题一个订单二维数组,一维子数组有两项,第一项订单编号,第二项库存。要求把库存为0的移到后面,库存多的放到前面,且不改变这些编号原有的顺序。比如都是一百个库存,原来3号商品在5号商品前面,移动以后不能变到5号后面了;库存为0的商品同理。其实sort一下就好了,第一遍是70%还是30%来着,脑抽了,只对外循环处理了一遍;第二个题公司IPO&nbsp;LeetCode&nbsp;502;第三个题目两个升序数组合并,且第一个数组足够长,可以容纳(m+n),m为数组一长度,n为数组2长度,解法:i=m-1,j=n-1;tail=m+n-1。比较两个数组尾部,大的数据放到nums1的末尾。移动下标。最后如果nums2还没插入完成(j&gt;=0),继续尾插。
查看12道真题和解析
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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