【笔试刷题】蚂蚁-2026.03.15-开发岗-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

蚂蚁-2026.03.15-开发岗

这一套更像标准开发岗配置:第 1 题是计数加一点几何合法性判断,第 2 题要把翻转操作抽象成位置可取值范围,第 3 题则是典型的“看似可以乱试,实则有稳定二进制贪心结论”的数论题。整体不算偏,但第 2、3 题都要求先把题目重新翻译成更顺手的数学对象。

题目一:房屋骨架搭建

这题的关键不是模拟拼房子,而是先看一根房子骨架到底需要几对等长木棍。把问题化成“总共能不能凑出至少 3 对”之后,判断就变得非常直接。容易卡壳的点在于三角形是否合法,其实只要从三对里合理分配,条件天然满足。

难度:简单

题目二:翻转数组后的好二元组最大值

题面操作很多,但位置 最终只会在 之间二选一,所以核心是统计有多少位置能落到“小于等于 ”这一侧。把可行的 区间推出来以后,答案就是最大化 。真正容易错的是上下界分类,尤其是哪些点“可选”、哪些点“必选”。

难度:中等

题目三:幂次加法下的最少追平次数

把两数追平,等价于用最少个带符号的二进制幂表示差值,这就是 NAF 的经典模型。题目表面像搜索,实际上每次只需要根据奇偶和模 4 情况贪心缩小差值。这里最值得记住的不是公式本身,而是为什么 可以写成 ,从而比普通二进制拆分更优。

难度:中等偏难

1. 房屋骨架搭建

问题描述

K 小姐手里有一批木棍,想搭出一个“房子”形状:

  • 下半部分是一个长方形;
  • 上半部分是一个等腰三角形;
  • 长方形的上边同时也是三角形的底边。

每根木棍长度都是正整数,并且每根木棍最多使用一次。

请你判断,是否能从这些木棍中挑出若干根,恰好拼出这样的房子。

输入格式

第一行输入一个整数 ,表示木棍数量。

第二行输入 个整数 ,表示每根木棍的长度。

输出格式

如果能够拼出这样的房子,输出 YES;否则输出 NO

样例输入 1

6
4 4 3 3 5 5

样例输出 1

YES

样例输入 2

6
4 4 3 3 2 1

样例输出 2

NO

数据范围

题解

先把房子的边数想清楚。

这个图形虽然看起来像“长方形 + 三角形”,但由于两部分共用了一条边,所以真正需要的边是:

  • 长方形的上下边各一根;
  • 长方形的左右边各一根;
  • 屋顶的两条腰各一根。

总共需要 根木棍,也就是 3 对等长木棍

于是问题就变得非常直接了:

统计所有长度能提供的“成对木棍”数量之和,看看是否至少有 对。

设某个长度出现了 次,那么它最多能提供:

对木棍。

把所有长度贡献的对数加起来:

只要这个值不小于 ,答案就是 YES

为什么这样就够了

因为只要已经拿到了 对木棍:

  • 一对做宽;
  • 一对做高;
  • 一对做屋顶两条腰。

而三角形底边就是“宽”对应的那一对中的上边。

如果担心等腰三角形是否合法,只要把三对里最短的一对拿来做底边,另外任意一对做屋顶腰即可。因为屋顶腰长度是正整数,且不小于底边长度的一半,所以:

三角形一定能成立。

复杂度分析

只需要统计每种长度出现了多少次。

时间复杂度是 ,空间复杂度是 ,其中 是不同长度的数量。

参考代码

  • Python
import sys
from collections import Counter

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


def solve() -> None:
    n = int(input())
    arr = list(map(int, input().split()))
    cnt = Counter(arr)

    pairs = 0
    for v in cnt.values():
        pairs += v // 2

    print("YES" if pairs >= 3 else "NO")


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;
    unordered_map<int, int> cnt;
    for (int i = 0; i < n; ++i) {
        int x;
        cin >> x;
        ++cnt[x];
    }

    long long pairs = 0;
    for (auto &[k, v] : cnt) {
        pairs += v / 2;
    }

    cout << (pairs >= 3 ? "YES" : "NO") << '\n';
    return 0;
}
  • Java
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner fs = new FastScanner(System.in);
        int n = fs.nextInt();
        Map<Integer, Integer> cnt = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int x = fs.nextInt();
            cnt.put(x, cnt.getOrDefault(x, 0) + 1);
        }

        long pairs = 0;
        for (int v : cnt.values()) {
            pairs += v / 2;
        }

        System.out.println(pairs >= 3 ? "YES" : "NO");
    }

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

        FastScanner(InputStream is) {
            in = new BufferedInputStream(is);
        }

        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 <= ' ' && c != -1);
            int sign = 1;
            if (c == '-') {
                sign = -1;
                c = read();
            }
            int val = 0;
            while (c > ' ') {
                val = val * 10 + c - '0';
                c = read();
            }
            return val * sign;
        }
    }
}

2. 翻转数组后的好二元组最大值

问题描述

给定一个长度为 的数组,初始时满足:

定义一个有序对 为“好的二元组”,当且仅当:

你可以进行任意次操作。每次操作选择一个下标 ,把它的值改成:

请计算,在最优操作后,数组中最多能有多少个不同的好的二元组。

输入格式

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

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

接下来每组数据输入两个整数

输出格式

对于每组测试数据,输出一个整数,表示最多能得到多少个好的二元组。

样例输入

4
5 2
4 1
1 1
3 10

样例输出

6
4
0
0

数据范围

题解

这题看起来像是在改数组,实际上真正重要的只有一件事:

最终有多少个位置满足

设这个数量是 ,那么剩下满足 的位置数就是

由于好二元组是有序对,前一个位置来自“小的一侧”,后一个位置来自“大的一侧”,所以答案就是:

于是问题就转化成: 最多能取哪些值。

每个位置能取到什么值

初始时第 个位置是

操作一次之后,它会变成:

所以位置 最终只能在这两个值里二选一:

哪些位置能够变成“小于等于

一个位置能成为“小的一侧”,等价于它的两个候选值里至少有一个不大于

于是满足条件当且仅当:

因此,最终可以放进“小的一侧”的位置总数上界是:

哪些位置必定属于“小的一侧”

如果位置 的两个候选值都不大于 ,那它无论怎么翻转都只能算进小的一侧。

这要求同时满足:

也就是:

这样的点数为:

所以, 的可取范围就是:

如果原本 ,那么所有值都不大于 ,答案显然就是

最后怎么取最优

函数:

是一个开口向下的抛物线,在 最接近 的地方取到最大值。

所以只需要把 取成可行区间里最靠近 的整数即可。

复杂度分析

每组数据只需要做常数次计算。

时间复杂度是 ,空间复杂度是

参考代码

  • Python
import sys

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


def best_value(n: int, m: int) -> int:
    m = min(m, n)
    if m == n:
        return 0

    low = max(0, 2 * m - n)
    high = min(n, 2 * m)
    mid = n // 2

    ans = 0
    for x in (low, high, max(low, min(high, mid)), max(low, min(high, mid + 1))):
        ans = max(ans, x * (

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

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

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

全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

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