【笔试刷题】团子-2026.04.18-算法岗-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

🤖 内容包含AI辅助生成,题解和代码均经过多轮验证,有问题欢迎评论

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

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

团子-2026.04.18-算法岗

1. 小兰的批量清洗保留表

问题描述

小兰在整理一张长度为 的记录表,表中的第 项权值为

他会连续进行 轮清洗。每一轮都执行下面的规则:

  • 删除当前表中权值最小的一项;
  • 如果最小值出现了多次,就删掉其中位置最靠前的那一项。

清洗结束后,剩余记录的相对顺序保持不变。请输出最后留下来的序列。

输入格式

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

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

对于每组数据:

  • 第一行输入两个整数
  • 第二行输入 个整数

输出格式

对于每组数据,输出一行,表示完成 轮清洗后的序列。

剩余元素之间用一个空格分隔。

样例输入

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

样例输出

3 4 5
1 2 3
5

样例说明

  • 第一组里,两个最小值都是 ,要先删位置更靠前的那个,再删另一个 ,最后剩下 3 4 5
  • 第二组不需要清洗,原序列直接保留。
  • 第三组删掉前四轮最小值后,只剩下最大的 5

数据范围

  • 单个测试文件中所有 的总和不超过

题解

每一轮删掉的其实就是当前还没被删掉的最小二元组

这里的真正要抓的是:

  • 比较优先级先看值
  • 值相同的时候再看下标 ,下标小的会更早被删。

所以完全没必要真的删 次。把所有位置写成二元组 后整体排一次序,排在最前面的 个位置,就是最终会被删掉的那 项。

拿到这 个下标以后,再按原顺序扫一遍数组,把没被标记的位置输出出来即可。

复杂度分析

  • 排序复杂度是
  • 标记和输出都是线性复杂度。
  • 因此单组总复杂度为 ,可以通过数据范围。

参考代码(Python)

import sys

def input() -> str:
    return sys.stdin.readline().strip()

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

    for _ in range(t):
        n, m = map(int, input().split())
        arr = list(map(int, input().split()))

        # 把每个元素写成 (值, 原下标)。
        # 排序后最前面的 m 个位置,就是最终会被清洗掉的记录。
        ords = [(arr[i], i) for i in range(n)]
        ords.sort()

        removed = [False] * n
        for k in range(m):
            removed[ords[k][1]] = True

        # 剩余元素的相对顺序不变,按原数组顺序输出即可。
        cur = []
        for i, x in enumerate(arr):
            if not removed[i]:
                cur.append(str(x))
        out.append(" ".join(cur))

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

if __name__ == "__main__":
    solve()

2. 小兰的门店营业额预测

问题描述

小兰收集了一批门店样本。每个训练样本都包含:

  • 门店的位置坐标
  • 对应的营业额

现在他想用固定参数的高斯过程回归模型,对另一批测试位置的营业额均值进行预测。

本题中核函数和参数都已经固定:

  • 长尺度
  • 信号方差
  • 噪声方差

因此核函数可以直接写成

训练阶段需要使用矩阵 ,并按闭式公式完成预测。

输入格式

输入是一行 JSON 对象,包含两个字段:

  • train:训练样本数组。每个元素的最后一列是营业额,其余列是坐标。
  • test:测试位置数组。每个元素只包含坐标。

坐标维度只会是 ,并且训练与测试的维度一致。

输出格式

输出一行 JSON 数组,表示每个测试点对应的预测均值。

样例输入

{"train":[[-1,-1],[1,1]],"test":[[-1],[0],[1]]}

样例输出

[-0.896337, 0.0, 0.896337]

样例说明

  • 训练样本里一共有两个点,坐标分别是 ,营业额分别是
  • 代入固定核函数和噪声项后,就能按公式算出三个测试点的预测均值。

数据范围

  • 坐标维度
  • 训练样本数满足
  • 测试样本数满足
  • 所有输入值都是实数,且不存在缺失

题解

这题没有超参数学习,也不需要做任何优化搜索,直接按公式实现即可。

1. 先把输入拆成训练坐标和目标值

训练数组里的每一行都长成 ,所以最后一列是营业额,前面 列是坐标。

2. 构造训练核矩阵

设训练点个数是 ,那么矩阵大小就是

项为 ,对角线上再额外加上噪声项

3. 解线性方程组

预测公式可以写成

与其真的去求逆矩阵,不如直接解线性方程组 ,然后再用

因为 ,直接用带部分主元的高斯消元就够了。

4. 输出格式

题面要求输出 JSON 数组。这里统一保留到小数点后 位,再去掉末尾多余的零,但至少保留一位小数。

复杂度分析

  • 构造核矩阵复杂度是
  • 高斯消元复杂度是
  • 预测全部测试点复杂度是

由于 ,这些复杂度都非常轻松。

参考代码(Python)

import sys
import json
import math

def input() -> str:
    return sys.stdin.readline().strip()

def gauss(mat):
    n = len(mat)
    for col in range(n):
        # 选绝对值最大的主元,数值会稳定一些。
        pivot = col
        for row in range(col + 1, n):
            if abs(mat[row][col]) > abs(mat[pivot][col]):
                pivot = row
        mat[col], mat[pivot] = mat[pivot], mat[col]

        div = mat[col][col]
        for j in range(col, n + 1):
            mat[col][j] /= div

        for row in range(n):
            if row == col:
                continue
            factor = mat[row][col]
            if abs(factor) < 1e-12:
                continue
            for j in range(col, n + 1):
                mat[row][j] -= factor * mat[col][j]

    return [mat[i][n] for i in range(n)]

def kernel(a, b):
    sq = 0.0
    for x, y in zip(a, b):
        diff = x - y
        sq += diff * diff
    return math.exp(-0.5 * sq)

def fmt(val):
    if abs(val) < 5e-7:
        val = 0.0
    text = f"{val:.6f}".rstrip("0").rstrip(".")
    if "." not in text:
        text += ".0"
    if text == "-0.0":
        text = "0.0"
    return text

def solve() -> None:
    data = json.loads(sys.stdin.read().strip())
    train = data["train"]
    test = data["test"]

    n = len(train)
    d = len(train[0]) - 1

    x_train = [row[:d] for row in train]
    y_train = [row[d] for row in train]

    # 构造增广矩阵 [K | y]。
    mat = [[0.0] * (n + 1) for _ in range(n)]
    for i in range(n):
        for j in range(n):
            mat[i][j] = kernel(x_train[i], x_train[j])
        mat[i][i] += 0.1
        mat[i][n] = y_train[i]

    alpha = gauss(mat)

    ans = []
    for point in test:
        pred = 0.0
        for i in range(n):
            pred += alpha[i] * kernel(x_train[i], point)
        ans.append(fmt(pred))

    print("[" + ", ".join(ans) + "]")

if __name__ == "__main__":
    solve()

3. 小兰的倍频多重集对齐

问题描述

小兰正在调试一组能量模块。当前有两个长度都为 的数组

在一次操作中,他可以在数组 里选出若干个当前数值完全相同的元素,并把它们同时乘以

他想经过若干次操作后,让数组 的元素多重集合与数组 完全一致。这里不要求位置一一对应,只要求每个数出现的次数相同。

请输出最少需要多少次操作。如果无论怎么做都不可能完成,输出

输入格式

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

对于每组数据:

  • 第一行输入一个整数
  • 第二行输入 个整数,表示数组
  • 第三行输入 个整数,表示数组

输出格式

对于每组数据,输出一行一个整数,表示最少操作次数。

样例输入

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

样例输出

2
2
-1

样例说明

  • 第一组里,把 1 变成 2 算一次操作,再把 2 变成 4 算一次操作,一共两次。
  • 第二组里,可以先把一个 1 翻倍成 2,再把一个 2 翻倍成 4
  • 第三组中,9 的奇数部分是 9,而数组 里没有办法通过不断乘 造出这个奇数部分,所以无解。

数据范围

  • 所有测试用例中 的总和不超过

题解

这题里真正不会变化的是一个数的奇数部分

如果把一个正整数不断除以 ,直到它变成奇数,那么这个奇数

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

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

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

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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