ARTICLE · 1355967
中国电信11月14日机考笔试题与解析
写在前面
本次给大家带来2026年11月14日中国电信笔试题的3道题,本场机考题目可在咱们平台上在线刷题。
大厂笔试AI Coding练习:CodeFun2000.com/aicoder-gym
第1题-标签合格统计
题目内容
给定一个只含小写字母与分隔字符 # 的串,这些分隔字符会把它拆分成若干段非空的标签。
对某个标签,若下面三条同时成立就把它算作合格:它的第一个字符和最后一个字符不相同;其中属于元音 a/e/i/o/u 的字符个数是奇数;它内部出现的字母种类不少于 种。请求出合格标签一共有几个、全部合格标签的长度加起来是多少,以及合格标签里最长的那个有多长。
统计字母种类时,只看这一个标签自身含有哪些互不相同的小写字母。
输入描述
一行,给出字符串 ,其长度记为 。 的开头和结尾都不会是 #,任意两个相邻的 # 中间至少夹着一个小写字母。
里只会出现小写字母和 #。
输出描述
在一行内输出三个整数;当一个合格标签也没有时,最长长度那一项为 。
如果找不到任何合格的标签,那么后两个整数也都输出 。
样例1
输入
queen#ab#idea#strip#cub输出
4 17 5说明
queen:开头q、结尾n互异,元音u、e、e共 个,字母种类 种,合格。ab:字母种类只有 种,不合格。idea:开头i、结尾a互异,元音i、e、a共 个,字母种类 种,合格。strip:首尾s、p不同,元音只有i一个,字母种类 种,合格。cub:首尾c、b不同,元音只有u一个,字母种类 种,合格。合格标签共 个,长度之和为 ,其中最长的长度为 。
题解
解题思路
本题是一道字符串模拟题,按 # 把串切开后逐个标签检查即可。
用分隔符 #把字符串 切成若干标签,题目保证每个标签都非空。对每个标签统计两样东西: 元音 a/e/i/o/u出现的次数;出现过的不同字母的种类数,可以用一个长度为 的布尔数组(或集合)记录。 同时满足下面三条的标签才算合格: 首字符和末字符不同; 元音个数为奇数; 字母种类数不少于 。 对合格标签累加三个答案:个数加 ,长度总和加上它的长度,最大长度取较大值。 没有合格标签时三个答案保持初始值 ,直接输出即可。
复杂度分析
时间复杂度:,每个字符只被扫描一次。 空间复杂度:,用于保存输入串(切分后的标签总长也是 )。
代码实现
python代码(C++和JAVA代码见平台)
import sysdefsolve(t): cnt = total = best = 0for g in t.split('#'):# 统计元音个数 vowels = sum(1for ch in g if ch in'aeiou')# 首尾不同、元音奇数、种类至少 3 种if g[0] != g[-1] and vowels % 2 == 1and len(set(g)) >= 3: cnt += 1 total += len(g) best = max(best, len(g))return cnt, total, bestdefmain(): t = sys.stdin.readline().strip() print(*solve(t))main()第2题-网格棋盘差值
题目内容
小林手里有一张网格,每个格子里写着 0 或 1,行号和列号都从 开始编。每一次询问会给出一个闭合的子矩形,需要数出其中 1 的个数,同时算出它的棋盘加权差值:对坐标为 的格子,若 是偶数,格子里的 1 记 ;若 是奇数,则这个 1 记 ;写着 0 的格子不计入。
输入描述
首行给出三个整数 ,依次为网格的行数、列数以及询问的个数。
随后共 行,其中第 行是一个长为 的串,仅由 0 和 1 构成,描述网格的第 行。
再往后共 行,每行四个整数 ,表示所询问的子矩形覆盖第 行至第 行、第 列至第 列。
输出描述
每次询问单独占一行,输出两个整数:先是该子矩形里 1 的个数,再是它的棋盘加权差值。
样例1
输入
3 4 30110110110111 2 1 22 1 3 21 1 3 4输出
1 -13 18 2说明
询问 1 2 1 2:只有格子 ,它是1,且 为奇数,记 ,所以输出1 -1。询问 2 1 3 2:1落在 、、,分别记 ,共 个,差值为 。询问 1 1 3 4:整张网格有 个1,其中 、、、、 记 ,、、 记 ,差值为 。
题解
解题思路
本题考查二维前缀和。询问次数多达 ,每次都逐格统计会超时,所以先预处理,再让每次询问 回答。
把两个要求的量都看成「每个格子有一个权值,求子矩形权值和」: 1的个数:格子是1时权值为 ,否则为 ;棋盘加权差值:格子是 1且 为偶数时权值为 ,为奇数时权值为 ,格子是0时权值为 。对两种权值分别建二维前缀和, 表示左上角 到右下角 的权值和:。 询问 时用容斥求子矩形和:。 两张前缀和表各算一次,依次输出个数和差值即可。
复杂度分析
时间复杂度:,预处理扫一遍网格,每次询问 。 空间复杂度:,两张前缀和表。
代码实现
python代码(C++和JAVA代码见平台)
import sysdefbuild(H, W, grid):# cnt 统计 1 的个数,wsum 统计棋盘加权和,下标从 1 开始 cnt = [[0] * (W + 1) for _ in range(H + 1)] wsum = [[0] * (W + 1) for _ in range(H + 1)]for x in range(1, H + 1): row = grid[x - 1]for y in range(1, W + 1): v = 1if row[y - 1] == '1'else0 w = v if (x + y) % 2 == 0else -v # 奇数格的 1 记 -1 cnt[x][y] = cnt[x - 1][y] + cnt[x][y - 1] - cnt[x - 1][y - 1] + v wsum[x][y] = wsum[x - 1][y] + wsum[x][y - 1] - wsum[x - 1][y - 1] + wreturn cnt, wsumdefarea(p, x1, y1, x2, y2):# 容斥求子矩形和return p[x2][y2] - p[x1 - 1][y2] - p[x2][y1 - 1] + p[x1 - 1][y1 - 1]defmain(): data = sys.stdin.buffer.read().split() H, W, k = int(data[0]), int(data[1]), int(data[2]) grid = [data[3 + i].decode() for i in range(H)] cnt, wsum = build(H, W, grid) pos = 3 + H out = []for _ in range(k): x1, y1, x2, y2 = map(int, data[pos:pos + 4]) pos += 4 out.append(f"{area(cnt, x1, y1, x2, y2)}{area(wsum, x1, y1, x2, y2)}") print("\n".join(out))main()第3题-连通块门票检查
题目内容
给定一张由 0 和 1 构成的网格,把 1 格子按上下左右相邻关系连成的极大连通块叫作一个组件。组件的大小指它包含的格子个数;组件的周长指它的格子与网格外部或者 0 格子相接的边的条数。
若一个组件的大小是奇数、周长是偶数,就说它能通过门票检查。请算出能通过的组件有几个、这些组件一共含有多少个格子,以及它们之中最大的周长。
输入描述
首行给出两个整数 ,依次为网格的行数与列数。
随后共 行,每行是一个长为 的串,只由字符 0 和 1 组成,描述这张网格。
输出描述
在一行内输出三个整数;当不存在能通过的组件时,最大周长那一项为 。
倘若没有任何组件能过门票检查,那么三个整数全都输出 。
样例1
输入
4 40111000111000101输出
2 4 8说明
组件 :大小为 ,是偶数,不能通过。 组件 :大小为 ,周长为 ,能通过。 组件 :大小为 ,周长为 ,能通过。 能通过的组件有 个,格子共 个,最大周长为 。
题解
解题思路
本题考查网格上的连通块搜索(BFS):找出每个由 1 组成的四连通块,边搜边统计大小和周长。
从左到右、从上到下扫描网格,遇到一个还没访问过的 1,就从它开始做一次 BFS,找出它所在的整个组件。BFS 取出一个格子时: 组件大小加 ; 依次看它上下左右四个方向,若越出网格或是 0,说明这条边在边界上,周长加 ;若是没访问过的 1,标记后加入队列。一个组件搜完后判断:大小为奇数且周长为偶数就通过,累加通过个数、格子总数,并更新最大周长。 补充一个性质:周长 大小 组件内相邻格子对数,所以周长一定是偶数,实际只需看大小的奇偶;代码里仍按题意两个条件都判断。 网格最多有 个格子,一条长链式的组件会让递归 DFS 爆栈,所以用队列实现的 BFS。
复杂度分析
时间复杂度:,每个格子只入队一次,每次检查 个方向。 空间复杂度:,用于访问标记和队列。
代码实现
python代码(C++和JAVA代码见平台)
import sysfrom collections import dequedefsolve(R, C, g): seen = [[False] * C for _ in range(R)] cnt = total = best = 0for i in range(R):for j in range(C):if g[i][j] != '1'or seen[i][j]:continue# 从 (i, j) 出发 BFS 整个组件 seen[i][j] = True q = deque([(i, j)]) size = per = 0while q: x, y = q.popleft() size += 1for nx, ny in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):if nx < 0or nx >= R or ny < 0or ny >= C or g[nx][ny] == '0': per += 1# 挨着网格外或 0,是一条周长边elifnot seen[nx][ny]: seen[nx][ny] = True q.append((nx, ny))# 大小为奇数且周长为偶数才通过if size % 2 == 1and per % 2 == 0: cnt += 1 total += size best = max(best, per)return cnt, total, bestdefmain(): data = sys.stdin.read().split() R, C = int(data[0]), int(data[1]) print(*solve(R, C, data[2:2 + R]))main()手机端刷题:塔子哥刷题宝















































































