阿里千文办公面试凉经(疑似)

本文最后更新于 2026年10月9日 早上

面试过程

这是这段时间我初次尝试面试,想看看如今相对前沿的公司需求是什么,也能更好帮助我确定后续学习方向,所以有了这次机会以后就稍微准备了一下参加这次面试。

我这次面试的职位是 千问办公-AI全栈开发实习生,面试的时候面试官深挖我的简历上的项目经历,特别是年初在深圳的那段实习,不过我对当时做的内容很熟悉,问到了自然就想起来了。然后问了些 Agent 相关的问题我这里简单总结几个:

  • 对于编码 Agent 来说,为什么会常用 grep、rg 这类检索工具而不是你前面提到的 zg 这种语义检索的工具?
  • 想象一个电商平台的大型代码库场景,你能描述一下 LLM Agent 是怎么根据用户简短的提示词(例:帮我看一下订单功能的代码)定位到某部分功能具体代码的过程吗?
  • 对于你实现的 Agent 来说,使用子 Agent 的优势是什么?(比如你设计了探索 Agent,为什么要用它?有什么好处?)
  • 你为什么要自己设计一个 Agent?它和市面上的 kimi、codex、claude code 这种 Agent 相比,优势是什么?
  • …

然后就到了我喜闻乐见(十分害怕,就是我知道要遭hhh)的环节,手撕代码,我其实没怎么成规模的刷过代码题,所以一看到面试官出了一道题就有点慌。但是面试官真的很好,看我一时间没什么思路就让我口述自己的想法。我先按自己的理解提了一个解法思路,面试官发现了一点问题,然后又举一些例子来引导我思考,最后硬是让我想出来了这道题怎么做(泪目,人真的太和善了)。我把面试里讨论的条件整理了一下,补上输入输出和样例,贴在下面供大家思考:

手撕题:按指定数量给苹果分组

题目描述

有 n 个苹果,编号为 1, 2, ..., n,需要将它们分成 m 个非空组。各组的苹果数量可以不同,但已由输入给定,记为 c_1, c_2, ..., c_m。

请给出任意一种满足以下条件的分组方案:

  1. 每个苹果恰好分到一个组中。
  2. 各组的苹果数量与给定数量一致。
  3. 同一组内不能出现相邻编号:对任意 1 <= i < n,苹果 i 和苹果 i + 1 必须属于不同的组。

如果不存在满足条件的方案,输出 -1。

组本身没有先后顺序,组内苹果的排列顺序也不影响结果。为便于描述输入输出,临时用 1...m 标记各组,并让第 k 组对应给定数量 c_k。

输入格式

  • 第一行包含两个整数 n 和 m,分别表示苹果总数和组数。
  • 第二行包含 m 个整数 c_1, c_2, ..., c_m,表示各组需要的苹果数量。

所有输入均为整数,且满足:

  • 1 <= m <= n;
  • 对任意 1 <= k <= m,有 c_k >= 1;
  • c_1 + c_2 + ... + c_m = n。

输出格式

若有解,在一行中输出 n 个用空格分隔的整数 g_1, g_2, ..., g_n。其中 g_i = k 表示编号为 i 的苹果分到第 k 组。

输出须满足:

  • 每个组号都在 1...m 范围内;
  • 组号 k 恰好出现 c_k 次;
  • 对任意 1 <= i < n,有 g_i != g_{i + 1}。

若有多种合法方案,输出任意一种即可;若无解,输出一行 -1。

示例一:存在合法分组

输入

1
2
8 3
4 3 1

一种合法输出

1
1 2 1 2 1 3 1 2

输出中的第 i 个数字就是 g_i,表示编号为 i 的苹果所属的组。例如,第 1 个数字是 1,表示苹果 1 在第 1 组;第 2 个数字是 2,表示苹果 2 在第 2 组。

苹果编号 1 2 3 4 5 6 7 8
所属组号 g_i 1 2 1 2 1 3 1 2

把上表按组号整理后,就是:

组号 苹果编号 数量
1 1、3、5、7 4
2 2、4、8 3
3 6 1

各组数量符合输入要求,且任意两个相邻编号的苹果都不在同一组。

示例二:无法满足要求

输入

1
2
4 2
3 1

输出

1
-1

解释

从编号 1, 2, 3, 4 中选出三个苹果,一定会包含相邻编号,因此无法组成需要三个苹果的那一组。

思路

然后我现在的解法思路如下:既然每一组填充数量是已知的,又要求同组内不能出现相邻的编号,所以可以先在第一组按 1,1+i,1+2i… 的形式(i=2)将一组一组填,1+i,加到后面以后加完了(到 n 的上限)继续 2,2+i …,接着填第2组直到第m组。这样每组内就不会有连续的编号苹果。什么情况下无解哪?比如我现在有 n 个苹果,那某一组的数量如果大于 (n+1)/2,那即使按上述分法,总会有数字落回到这个大组里而造成连续编号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 将输入组数从大到小排列
# 首先根据输入判断是否有解,判断标准是 m 内取最大的数然后和 (n+1)/2 比较,如果大于则无解,反之有解进入下一步
# 然后将当前 n 个数分组成奇数组和偶数组然后重排成新的数组
# 用新数组按组数从到小用新数组依次填每个组,填完以后处理结果并按标准格式输出

import sys


def solve():
data = list(map(int, sys.stdin.buffer.read().split()))

if len(data) < 2:
return

n, m = data[0], data[1]
counts = data[2:]

# 输入格式检查
if m <= 0 or len(counts) != m:
print(-1)
return

if n <= 0 or any(count <= 0 for count in counts):
print(-1)
return

if sum(counts) != n:
print(-1)
return

# 最大组数量不能超过交替位置的数量
limit = (n + 1) // 2
if max(counts) > limit:
print(-1)
return

# 按组数量从大到小排列。
# 保存原始组号,保证输出时仍然对应输入中的 c_i。
groups = sorted(
enumerate(counts, start=1),
key=lambda item: item[1],
reverse=True,
)

# 先使用奇数编号位置,再使用偶数编号位置。
# Python 下标从 0 开始,因此对应编号:
# 1, 3, 5, ..., 2, 4, 6, ...
positions = list(range(0, n, 2)) + list(range(1, n, 2))

answer = [0] * n
position_index = 0

for group_id, count in groups:
for _ in range(count):
answer[positions[position_index]] = group_id
position_index += 1

# 最终检查
if any(answer[i] == answer[i + 1] for i in range(n - 1)):
print(-1)
return

print(*answer)


if __name__ == "__main__":
solve()


阿里千文办公面试凉经(疑似)
https://catdfd.com/2026/09/30/阿里千文办公面试凉经/
作者
Gargantua
发布于
2026年9月30日
许可协议