夜雨聆风学习资料网

ARTICLE · 1355967

中国电信11月14日机考笔试题与解析

中国电信11月14日机考笔试题与解析

写在前面

本次给大家带来2026年11月14日中国电信笔试题的3道题,本场机考题目可在咱们平台上在线刷题。

大厂笔试AI Coding练习:CodeFun2000.com/aicoder-gym

题号
题目
核心做法
1
标签合格统计
模拟
2
网格棋盘差值
前缀和
3
连通块门票检查
BFS

第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 一个,字母种类  种,合格。
  • 合格标签共  个,长度之和为 ,其中最长的长度为 。

题解

解题思路

本题是一道字符串模拟题,按 # 把串切开后逐个标签检查即可。

  1. 用分隔符 # 把字符串  切成若干标签,题目保证每个标签都非空。
  2. 对每个标签统计两样东西:
    • 元音 a/e/i/o/u 出现的次数;
    • 出现过的不同字母的种类数,可以用一个长度为  的布尔数组(或集合)记录。
  3. 同时满足下面三条的标签才算合格:
    • 首字符和末字符不同;
    • 元音个数为奇数;
    • 字母种类数不少于 。
  4. 对合格标签累加三个答案:个数加 ,长度总和加上它的长度,最大长度取较大值。
  5. 没有合格标签时三个答案保持初始值 ,直接输出即可。

复杂度分析

  • 时间复杂度:,每个字符只被扫描一次。
  • 空间复杂度:,用于保存输入串(切分后的标签总长也是 )。

代码实现

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 时权值为 ,否则为 ;
    • 棋盘加权差值:格子是 1 且  为偶数时权值为 ,为奇数时权值为 ,格子是 0 时权值为 。
  2. 对两种权值分别建二维前缀和, 表示左上角  到右下角  的权值和:。
  3. 询问  时用容斥求子矩形和:。
  4. 两张前缀和表各算一次,依次输出个数和差值即可。

复杂度分析

  • 时间复杂度:,预处理扫一遍网格,每次询问 。
  • 空间复杂度:,两张前缀和表。

代码实现

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. 从左到右、从上到下扫描网格,遇到一个还没访问过的 1,就从它开始做一次 BFS,找出它所在的整个组件。
  2. BFS 取出一个格子时:
    • 组件大小加 ;
    • 依次看它上下左右四个方向,若越出网格或是 0,说明这条边在边界上,周长加 ;
    • 若是没访问过的 1,标记后加入队列。
  3. 一个组件搜完后判断:大小为奇数且周长为偶数就通过,累加通过个数、格子总数,并更新最大周长。
  4. 补充一个性质:周长  大小  组件内相邻格子对数,所以周长一定是偶数,实际只需看大小的奇偶;代码里仍按题意两个条件都判断。
  5. 网格最多有  个格子,一条长链式的组件会让递归 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()
刷题练习:CodeFun2000.com

手机端刷题:塔子哥刷题宝

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料