【笔试刷题】电信-2025.10.17-改编真题
✅ 秋招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线180+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
电信-2025.10.17
题目一:小兰的魔法阵列
1️⃣:理解按位 OR 操作只会让二进制位从 0 变为 1 的特性
2️⃣:发现通过区间对称操作可以让所有元素共享二进制位
3️⃣:计算所有元素的按位 OR 值作为答案
难度:中等
这道题的关键在于理解按位 OR 操作的单调性和区间对称操作的本质。通过分析发现,无论数组长度如何,最终都能让每个元素包含原数组所有元素的所有二进制 1 位。因此答案就是所有元素的按位 OR 值,可以用 O(n) 的时间复杂度解决。
题目二:小基的收藏品统计
1️⃣:枚举所有可能的子数组起点和终点
2️⃣:使用哈希表维护当前子数组每个元素的出现次数
3️⃣:维护最高频次和达到最高频次的元素个数
4️⃣:当只有一个元素达到最高频次时更新答案
难度:中等
这道题需要找出具有唯一众数的最长子数组。由于数据范围较小(n ≤ 2000),可以采用 O(n²) 的暴力枚举方法。关键是在枚举过程中高效维护当前子数组的状态信息,包括每个元素的出现次数、最高频次以及达到最高频次的元素个数。
题目三:小毛的智能灯控系统
1️⃣:分析每盏灯被触发的条件(倍数关系或因子关系)
2️⃣:计算倍数贡献:使用除法快速统计
3️⃣:计算因子贡献:枚举到根号 j 找出所有因子
4️⃣:判断总触发次数的奇偶性决定灯的状态
难度:中等
这道题结合了数论和模拟的思想。关键是理解整除关系的双向性(因子和倍数),并高效计算每盏灯被触发的总次数。通过数学分析,可以将问题转化为计算因子数和倍数个数,使用根号分解的技巧可以在 O(√n) 的时间内处理每盏灯,整体复杂度为 O(n√n)。
01. 小兰的魔法阵列
问题描述
小兰得到了一个由 个非负整数组成的魔法阵列
。她可以对这个阵列施放任意次(包括零次)魔法咒语,每次咒语的效果如下:
- 选择一个连续的区间
(满足
)
- 对区间内的元素进行对称增强:对于所有满足
的整数
,将位置
和位置
的元素同时更新为它们的按位或(OR)运算结果,即
小兰希望通过施放若干次咒语,使得阵列中的最小元素尽可能大。请你帮她计算能够达到的最小元素的最大可能值。
输入格式
第一行包含一个整数 (
),表示测试用例的组数。
对于每组测试用例:
第一行包含一个整数 (
),表示魔法阵列的长度。
第二行包含 个整数
(
),表示魔法阵列中的元素。
保证所有测试用例的 之和不超过
。
输出格式
对于每组测试用例,输出一行一个整数,表示通过若干次魔法操作后,阵列最小元素的最大可能值。
样例输入
2
3
1 2 3
5
6 6 6 6 6
样例输出
3
6
数据范围
- 所有测试用例的
之和不超过
| 样例 | 解释说明 |
|---|---|
| 样例1 | 对于阵列 |
| 样例2 | 阵列 |
题解
这道题的关键在于理解按位 OR 操作的特性和区间操作的本质。
首先,按位 OR 操作有一个重要性质:它只会让二进制位从 0 变成 1,不会让 1 变成 0。也就是说,一旦某个位置上的某个二进制位变成了 1,它就永远是 1 了。
其次,观察题目给出的操作:对于区间 ,我们可以让对称位置的元素进行 OR 操作。这意味着通过选择不同的区间,我们可以让数组中任意两个元素进行 OR 操作。
当 时,数组只有一个元素,无法进行操作,答案就是这个元素本身。
当 时,选择区间
,两个元素会同时更新为它们的 OR 值,最终两个元素相等。
当 时,通过选择不同长度和位置的区间,我们可以让任意元素"接触"到数组中的所有其他元素。例如:
- 选择区间
可以让
和
进行 OR
- 选择区间
可以让
和
进行 OR
- 通过多次操作的组合,最终所有元素都能"共享"彼此的二进制位
因此,无论数组长度是多少,最终我们都能让数组中的每个元素都包含原数组所有元素的所有二进制 1 位。换句话说,最终每个元素都能变成所有元素的按位 OR 值。
算法步骤:
- 读入数组
- 计算所有元素的按位 OR 值
- 输出这个 OR 值
时间复杂度:,只需遍历一次数组。
空间复杂度:,存储数组。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
t = int(input())
for _ in range(t):
n = int(input())
arr = list(map(int, input().split()))
# 计算所有元素的按位或
res = 0
for val in arr:
res |= val
print(res)
- 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 res = 0; // 存储所有元素的按位或结果
for (int i = 0; i < n; i++) {
long long x;
cin >> x;
res |= x; // 累积按位或
}
cout << res << "\n";
}
return 0;
}
- Java
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
while (t-- > 0) {
int n = Integer.parseInt(br.readLine());
String[] parts = br.readLine().split(" ");
long res = 0; // 存储所有元素的按位或结果
for (int i = 0; i < n; i++) {
long val = Long.parseLong(parts[i]);
res |= val; // 累积按位或运算
}
System.out.println(res);
}
}
}
02. 小基的收藏品统计
问题描述
小基有一个装满各种收藏品的柜子,每个收藏品都有一个编号。柜子里一共有 件收藏品,它们的编号分别是
(编号可以是任意整数,包括负数)。
小基想要从柜子中选出一段连续摆放的收藏品,使得这段收藏品中有一个明确的"主角"——也就是说,在这段收藏品中,出现次数最多的编号只有一个,而不是有多个编号并列第一。
现在,小基想知道满足这个条件的最长连续收藏品段有多长。如果不存在这样的收藏品段,请输出 。
名词解释:
连续收藏品段:指柜子中一段连续摆放的收藏品 (
)。
主角(唯一众数):在一段收藏品中,出现次数最多的编号。如果有多个编号的出现次数都是最多且相同,则不存在"主角"。
输入格式
第一行包含一个整数 (
),表示测试用例的组数。
对于每组测试用例:
第一行包含一个整数 (
)。
第二行包含 个整数
(
)。
保证所有测试用例的 之和不超过
。
输出格式
对于每组测试用例,输出一行一个整数,表示存在唯一众数的最长收藏品段长度。如果不存在,输出 。
样例输入
3
5
1 2 2 3 3
3
7 7 7
4
1 1 2 2
样例输出
4
3
3
数据范围
- 所有测试用例的
之和不超过
| 样例 | 解释说明 |
|---|---|
| 样例1 | 整个数组 |
| 样例2 | 收藏品段 |
| 样例3 | 收藏品段 |
题解
这道题要求找出最长的子数组,使得该子数组有唯一的众数(出现次数最多的元素只有一个)。
由于数据范围不大(,所有测试用例的
之和不超过
),我们可以采用枚举所有子数组的暴力方法。
解题思路:
对于每个可能的起点 ,我们向右扩展终点
,并维护当前子数组的状态:
- 使用哈希表
cnt记录每个元素出现的次数 - 维护当前最高出现次数
maxFreq - 维护达到最高出现次数的元素个数
maxCnt
当我们向右扩展到位置 时:
- 将
的出现次数加1
- 如果新的出现次数超过了之前的最高次数,更新
maxFreq和maxCnt - 如果新的出现次数等于最高次数,将
maxCnt加1
当 maxCnt == 1 时,说明当前子数组有唯一众数,可以更新答案。
算法步骤:
- 枚举每个起点
- 对于每个起点,从
开始向右扩展终点
- 使用哈希表维护当前区间每个元素的出现次数
- 维护最高频次和达到最高频次的元素个数
- 当只有一个元素达到最高频次时,更新答案
时间复杂度:,两层循环枚举所有子数组。
空间复杂度:,哈希表存储元素频次。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
t = int(input())
for _ in range(t):
n = int(input())
a = list(map(int, input().split()))
ans = 0 # 记录最长长度
# 枚举起点
for l in range(n):
freq = {} # 记录每个元素出现次数
mx_f = 0 # 当前最高频次
mx_c = 0 # 达到最高频次的元素个数
# 枚举终点
for r in range(l, n):
# 将a[r]加入当前区间
freq[a[r]] = freq.get(a[r], 0) + 1
cur_f = freq[a[r]]
# 更新最高频次信息
if cur_f > mx_f:
mx_f = cur_f
mx_c = 1
elif cur_f == mx_f:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

