【笔试刷题】顺丰-2026.03.15-第二套-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

顺丰-2026.03.15-第二套

顺丰-2026.03.15-第二套

这套第二套整体偏基础,第一题是读完规则后直接按“行状态”收口,第二题虽然看起来像构造,实质只是在算可达的左右分组人数区间,第三题则是典型的二进制拆分。

题目一:整行黑化检验

题意里的矩阵规模很大,但约束只落在“某一行能不能既有黑格又有白格”。只要把问题缩到行状态,整题就是一次哈希判矛盾。

难度:Low

题目二:镜像阈值划分

真正需要最大化的是“最终不超过阈值的位置数”与“超过阈值的位置数”的乘积。把每个位置拆成“必在左侧 / 必在右侧 / 可自由选”三类以后,就变成简单的区间最优化。

难度:Mid

题目三:补幂对齐

最优策略不是两边一起折腾,而是直接把较小值补到较大值。差值按二进制展开后有多少个 1,答案就是多少步。

难度:Low

整行黑化检验

问题描述

小基 正在核对一张 的方格记录表。每个格子最终都会被染成黑色或白色。

这张表必须满足一个规则:

  • 只要某一行里出现过一个黑色格子,那么这一行的所有格子都必须是黑色。

现在已经知道其中 个位置的颜色,其余位置还没有确定。请判断,是否存在一种补全方式,使整张表满足这个规则。

输入格式

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

对于每组数据:

  • 第一行输入两个整数
  • 接下来 行,每行输入两个整数 和一个字符
  • ,表示该位置是黑色;若 ,表示该位置是白色。

保证所有给出的坐标互不相同。

输出格式

对每组数据输出一行:

  • 若存在合法补全方案,输出 Yes
  • 否则输出 No

样例输入

2
5 4
1 1 B
1 2 B
2 1 B
2 2 B
5 4
1 1 B
1 2 B
2 1 W
2 2 B

样例输出

Yes
No

数据范围

样例 解释说明
样例 1 第一组里,第 行和第 行都只出现了黑格,可以把它们整行补成黑色,其余位置补成白色。第二组里,第 行同时出现了白格和黑格,这一行无论怎么补都不可能合法。

题解

别被矩阵规模吓到,这题真正受限制的只有“行”。

因为规则写得很直接:

  • 某一行只要出现一个黑格,这一行就必须整行全黑。

于是每一行只有三种状态:

  1. 目前还没有已知信息。
  2. 这一行已经出现过黑格,因此必须整行全黑。
  3. 这一行已经出现过白格,因此不可能整行全黑。

顺着输入扫一遍即可:

  • 若当前格子是黑色,而这一行之前已经出现过白格,立刻矛盾。
  • 若当前格子是白色,而这一行之前已经被要求全黑,也立刻矛盾。

只要没有出现矛盾,就一定能构造合法方案:

  • 所有“必须全黑”的行,把剩余未知格子全部补成黑色。
  • 其余行把剩余未知格子全部补成白色。

所以判断条件就是:同一行里不能同时出现黑格和白格。

复杂度分析

每个已知格子只处理一次,时间复杂度是

用哈希表记录出现过的行状态,空间复杂度是

参考代码

  • Python
import sys

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


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

    for _ in range(t):
        n, m = map(int, input().split())
        row = {}
        ok = True

        for _ in range(m):
            x, y, c = input().split()
            x = int(x)

            st = row.get(x, 0)
            if c == "B":
                if st == 2:
                    ok = False
                else:
                    row[x] = 1
            else:
                if st == 1:
                    ok = False
                else:
                    row[x] = 2

        out.append("Yes" if ok else "No")

    sys.stdout.write("\n".join(out))


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--) {
        long long n;
        int m;
        cin >> n >> m;

        unordered_map<long long, int> row;
        bool ok = true;

        for (int i = 0; i < m; ++i) {
            long long x, y;
            char c;
            cin >> x >> y >> c;

            int st = row.count(x) ? row[x] : 0;
            if (c == 'B') {
                if (st == 2) {
                    ok = false;
                } else {
                    row[x] = 1;
                }
            } else {
                if (st == 1) {
                    ok = false;
                } else {
                    row[x] = 2;
                }
            }
        }

        cout << (ok ? "Yes" : "No") << '\n';
    }
    return 0;
}
  • Java
import java.io.*;
import java.util.*;

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

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

        String next() throws IOException {
            StringBuilder sb = new StringBuilder();
            int c;
            do {
                c = read();
            } while (c <= 32);
            while (c > 32) {
                sb.append((char) c);
                c = read();
            }
            return sb.toString();
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }
    }

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

        while (t-- > 0) {
            long n = fs.nextLong();
            int m = fs.nextInt();
            HashMap<Long, Integer> row = new HashMap<>();
            boolean ok = true;

            for (int i = 0; i < m; i++) {
                long x = fs.nextLong();
                long y = fs.nextLong();
                char c = fs.next().charAt(0);

                int st = row.getOrDefault(x, 0);
                if (c == 'B') {
                    if (st == 2) {
                        ok = false;
                    } else {
                        row.put(x, 1);
                    }
                } else {
                    if (st == 1) {
                        ok = false;
                    } else {
                        row.put(x, 2);
                    }
                }
            }

            ans.append(ok ? "Yes" : "No").append('\n');
        }

        System.out.print(ans);
    }
}

镜像阈值划分

问题描述

小基 手里有 张编号牌,初始时第 张牌上的数字就是

对于每一张牌,都可以选择是否执行一次镜像翻转。翻转后,这张牌上的数字会变成:

也就是说,第 张牌最终只能取两个值

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

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

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

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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