蚂蚁笔试 蚂蚁笔试题 蚂蚁0319春招实习笔试真题
笔试时间:2026年3月19日
往年笔试合集:
第一题:奇偶消除操作
题目
给定一个长度为 n 的数组 a。你可以进行若干次操作,每次操作从下列两种中任选其一:
- 选择一个元素将其删除,剩余元素按照原顺序拼接;
- 选择一个元素将其增加 1 或者减少 1。
要求:每次操作完成后,数组所有元素的和必须是 2 的倍数(即为偶数)。请你输出最多可以进行多少次操作。
输入描述
每个测试文件均包含多组测试数据。第一行输入一个整数 T 表示数据组数,每组测试数据描述如下:
- 第一行输入一个整数 n(1 ≤ n ≤ 10⁵)表示数组长度;
- 第二行输入 n 个整数 a₁, a₂, ..., aₙ(1 ≤ aᵢ ≤ 10⁹)表示数组 a。
除此之外,保证单个测试文件的 n 之和不超过 10⁵。
输出描述
对于每一组测试数据,新起一行,输出一个整数,表示最多可以进行的操作次数。
样例输入
2 5 1 2 3 4 5 4 2 2 1 1
样例输出
4 2
样例说明
样例解释(对应第一组):初始元素和为奇数,可以先对某个奇数元素执行一次 ±1,使总和变为偶数;此后总和为偶数,只能删除偶数元素,直至无法继续;共可操作 4 次。
参考题解
解题思路:
数组和为偶数的本质是奇数的个数为偶数。每次操作后都要满足这个条件。
- 对一个数做 ±1:代价是 1 次操作,会改变它的奇偶性。
- 删除一个元素:代价是 1 次操作,会直接移除它(同时改变奇数计数)。
我们希望尽可能多操作,所以要尽量少用高代价的方式。初始时统计数组中奇数的个数 cnt_odd:
- 如果
cnt_odd是偶数:可以直接开始删除元素,每次删除只能删偶数元素(否则奇数个数会变成奇数,不满足条件),直到没有偶数可删为止。 - 如果
cnt_odd是奇数:必须先做 1 次 ±1 操作,把某个奇数变成偶数(让cnt_odd变为偶数),之后再开始删除偶数元素。
因此答案为:若 cnt_odd 为奇数,则答案 = 1 + (cntEven + 1);若 cnt_odd 为偶数,则答案 = cntEven。
C++
#include <iostream>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int cntOdd = 0, cntEven = 0;
for (int j = 0; j < n; j++) {
int num;
cin >> num;
if (num % 2 == 1) {
cntOdd++;
} else {
cntEven++;
}
}
int res = 0;
if (cntOdd % 2 == 1) {
res += 1; // 先做一次 ±1 操作,将一个奇数变为偶数
cntOdd--;
cntEven++;
}
res += cntEven; // 之后删除所有偶数元素
cout << res << endl;
}
return 0;
}
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
for (int i = 0; i < t; i++) {
int n = scanner.nextInt();
int cntOdd = 0, cntEven = 0;
for (int j = 0; j < n; j++) {
int num = scanner.nextInt();
if (num % 2 == 1) {
cntOdd++;
} else {
cntEven++;
}
}
int res = 0;
if (cntOdd % 2 == 1) {
res += 1;
cntOdd--;
cntEven++;
}
res += cntEven;
System.out.println(res);
}
}
}
Python
import sys
input = sys.stdin.readline
def solve():
t = int(input())
for _ in range(t):
n = int(input())
a = list(map(int, input().split()))
cnt_odd = 0
cnt_even = 0
for num in a:
if num % 2 == 1:
cnt_odd += 1
else:
cnt_even += 1
res = 0
if cnt_odd % 2 == 1:
res += 1 # 先做一次 ±1 操作,将一个奇数变为偶数
cnt_odd -= 1
cnt_even += 1
res += cnt_even # 之后删除所有偶数元素
print(res)
solve()
第二题:这里没有三角形
题目
给定一个正整数 n(1 ≤ n ≤ 10⁵),表示需要构造的数组长度;构造一个长度为 n 的数组 a,使其满足以下条件:
- 1 ≤ aᵢ ≤ 10⁹;
- 任意选择三个不同下标 i, j, k,设相应的数组元素按非降序排列为 x ≤ y ≤ z,则有 x + y ≤ z,即无法组成三角形。
输入描述
在一行上输入一个整数 n(1 ≤ n ≤ 10⁵),表示数组长度。
输出描述
若存在满足条件的数组,则输出一行 n 个整数 a₁, a₂, ..., aₙ;否则,输出 -1。如果存在多个解决方案,您可以输出任意一个,系统会自动判定是否正确。
样例输入
3
样例输出
1 2 4
参考题解
解题思路:
对于给定的 n,我们需要构造一个长度为 n 的数组,使得任意三个不同下标对应的数,按非降序排列后满足 x + y ≤ z,即无法构成三角形。这样的数组必须满足递增序列中每一项不小于前两项之和,应取斐波那契数列(从 1, 1 开始)为最紧凑的构造方式。
计算可知,在 10⁹ 范围内最多能构造 44 项。因此,当 n ≤ 44 时,输出斐波那契数列的前 n 项;否则输出 -1。
C++
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
if (n > 44) {
cout << -1 << endl;
} else {
long long a[45];
a[0] = 1;
if (n > 1) a[1] = 1;
for (int i = 2; i < n; i++) {
a[i] = a[i - 1] + a[i - 2];
}
for (int i = 0; i < n; i++) {
cout << a[i];
if (i < n - 1) cout << " ";
}
cout << endl;
}
return 0;
}
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
if (n > 44) {
System.out.println(-1);
} else {
long[]
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
