【笔试刷题】蚂蚁-2026.03.19-研发岗-改编真题
✅ 春招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线200+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
蚂蚁-2026.03.19-研发岗
蚂蚁-2026.03.19-研发岗
这套研发岗的节奏很清楚:第一题是抓奇偶不变量的签到题;第二题看起来像构造,实质是在问“多长的无三角 multiset 还能塞进 ”;第三题则是把一次整体调权操作还原成“只消跨界逆序对”,再用树状数组做前后缀逆序统计。整体不算偏,但第 2、3 题都要求先把题意化简成更顺手的数学对象。
题目一:货架校验的最长操作链
只要记住“每次操作后总和都必须是偶数”这一条,允许的动作类型就几乎被锁死了。总和已经是偶数时,只能删偶数;总和是奇数时,最佳开局是先把一个奇数加一或减一,顺手把它变成偶数,再一路删掉所有偶数。
难度:简单
题目二:无法成三角的展品长度表
把数组排序后,要求任意三元组都不能成三角形,本质上就是对每个位置都要满足“前两个最大值之和不超过当前值”。最慢增长的合法序列正是从 开始的 Fibonacci,因此长度上限直接由
截断出来。
难度:中等
题目三:分界调权后的最小逆序数
一次操作同时把左段整体减去 、右段整体加上
,段内相对大小不变,真正会变化的只有跨分界线的逆序对。只要选足够大的正数,就能把跨界逆序对全部消掉,于是答案就变成“某个前缀的逆序对 + 后缀的逆序对”的最小值。
难度:中等
1. 货架校验的最长操作链
问题描述
小基 正在检查一排货架上的编号序列。
给定一个长度为 的数组
,她可以进行若干次操作。每次操作只能二选一:
- 删除一个元素,剩余元素按原顺序重新拼接;
- 选择一个元素,把它增加
或减少
。
但系统有一条硬性校验规则:
- 每次操作完成后,数组中所有元素的和都必须是偶数。
请计算,最多能够进行多少次操作。
输入格式
每个测试文件均包含多组测试数据。
第一行输入一个整数 ,表示数据组数。
对于每组数据:
- 第一行输入一个整数
,表示数组长度。
- 第二行输入
个整数
,表示数组中的元素。
除此之外,保证单个测试文件的 之和不超过
。
输出格式
对于每组数据输出一行一个整数,表示最多能够进行的操作次数。
样例输入
2
5
1 2 3 4 5
4
2 2 1 1
样例输出
4
2
数据范围
| 样例 | 解释说明 |
|---|---|
| 样例 1 | 第 1 组数据先把某个奇数改成偶数,再删掉所有偶数,一共可以做 |
题解
这题真正限制操作数量的,不是“删元素”还是“加减一”,而是那句:
- 每次操作后,总和必须是偶数。
先看哪类操作会改变总和奇偶
- 删除一个偶数,总和奇偶不变。
- 删除一个奇数,总和奇偶翻转。
- 对某个元素加一或减一,总和奇偶也会翻转。
这就带来一个直接结论:
- 如果当前总和已经是偶数,那么下一步只能执行“不会翻转奇偶”的操作,也就是删除一个偶数。
因此一旦总和变成偶数,后面就再也不能删奇数、也不能继续做 操作了。
情况 1:初始总和就是偶数
此时从第一步开始就只能删偶数。
所以答案就是数组里偶数的个数。
情况 2:初始总和是奇数
这时第一步必须把总和改成偶数。
可以选的方式有两类:
- 删除一个奇数;
- 把某个元素加一或减一。
其中最优的一定是对某个奇数做一次 :
- 这次操作本身算
次;
- 一个奇数会被改成偶数,于是数组里的偶数个数还会额外增加
;
- 之后再把所有偶数删掉即可。
设原数组中偶数个数是 ,那么总操作数就是:
而如果第一步选择删掉一个奇数,那么后面只能删原来的偶数,总共只有 次,不如前一种做法。
结论
- 若数组总和为偶数,答案是
偶数个数。 - 若数组总和为奇数,答案是
偶数个数 + 2。
复杂度分析
每组数据只需要扫描一遍数组。
- 时间复杂度:
- 空间复杂度:
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def solve() -> None:
t = int(input())
out = []
for _ in range(t):
n = int(input())
arr = list(map(int, input().split()))
even = 0
total = 0
for x in arr:
total += x
if x % 2 == 0:
even += 1
if total % 2 == 0:
out.append(str(even))
else:
out.append(str(even + 2))
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--) {
int n;
cin >> n;
long long sum = 0;
int even = 0;
for (int i = 0; i < n; ++i) {
long long x;
cin >> x;
sum += x;
if ((x & 1LL) == 0) {
++even;
}
}
cout << ((sum & 1LL) ? even + 2 : even) << '\n';
}
return 0;
}
- Java
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args) throws Exception {
FastScanner fs = new FastScanner(System.in);
int t = fs.nextInt();
StringBuilder sb = new StringBuilder();
while (t-- > 0) {
int n = fs.nextInt();
long sum = 0L;
int even = 0;
for (int i = 0; i < n; i++) {
long x = fs.nextLong();
sum += x;
if ((x & 1L) == 0L) {
even++;
}
}
sb.append((sum & 1L) == 1L ? even + 2 : even).append('\n');
}
System.out.print(sb);
}
static class FastScanner {
private final InputStream in;
private final byte[] buf = new byte[1 << 16];
private int len = 0;
private int ptr = 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 {
return (int) nextLong();
}
long nextLong() throws IOException {
int c;
do {
c = read();
} while (c <= ' ' && c != -1);
int sign = 1;
if (c == '-') {
sign = -1;
c = read();
}
long val = 0;
while (c > ' ') {
val = val * 10 + c - '0';
c = read();
}
return sign == 1 ? val : -val;
}
}
}
2. 无法成三角的展品长度表
问题描述
展厅需要摆放一组长度标签。
给定一个正整数 ,请构造一个长度为
的正整数数组
,满足:
;
- 任意选出三个不同下标,对应的三个数按非降序排成
后,都有:
也就是说,任意三项都不能组成三角形。
如果存在合法构造,输出任意一组即可;如果不存在,输出 -1。
输入格式
输入一行一个整数 ,表示需要构造的数组长度。
输出格式
如果存在合法构造,输出一行 个整数;否则输出
-1。
样例输入
3
样例输出
1 1 2
数据范围
| 样例 | 解释说明 |
|---|---|
| 样例 1 | 1 1 2 中唯一的三元组满足 |
题解
把构造出的数组从小到大排序,记为:
题目的要求是:任意三个数都不能组成三角形。
对于排好序的三元组来说,只要检查:
其中 是三者中的最大值。
只需要盯住相邻的三个最大值
如果对每个 都有:
那么任意两个不超过 的更小元素,它们的和只会更小,自然也满足要求。
所以问题就变成了:
构造一个尽量慢增长的非降序序列,使得每一项都不小于前两项之和。
最慢增长就是 Fibonacci
为了让序列尽量长,每次都应该取最小可行值,于是有:
,对于
这正是 Fibonacci 序列:
为什么会有无解情况
因为题目还要求每个数不超过 。
而:
- 第
项 Fibonacci 是
- 第
项 Fibonacci 是
已经超过了 。
因此:
- 当
时,直接输出前
项 Fibonacci 即可;
- 当
时,无论怎么构造都不可能成功,输出
-1。
复杂度分析
只需要线性生成前 项。
- 时间复杂度:
- 空间复杂度:
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def solve() -> None:
n = int(input())
if n > 44:
print(-1)
return
fib = [0] * max(2, n)
fib[0] = 1
fib[1] = 1
for i in range(2, n):
fib[i] = fib[i - 1] + fib[i - 2]
print(*fib[:n])
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;
if (n > 44) {
cout << -1 << '\n';
return 0;
}
vector<long long> fib(max(2, n));
fi
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

查看1道真题和解析