【笔试刷题】OPPO-2026.03.14-改编真题
✅ 春招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线200+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
OPPO-2026.03.14
这套题的层次很清楚:第 1 题基本就是按题意模拟并做一次整除判断,属于热身;第 2 题虽然套了斐波那契背景,但真正考的是把带权区间和化成前缀公式;第 3 题的数据范围看起来很大,实际有效状态只和 这些数字有关,关键是先把“选集合”和“排顺序”拆开。
题目一:三号位求和校验
这题没有隐藏技巧,按下标扫描出所有位置是 的倍数的元素,再判断和是否能被
整除即可。最容易犯的错反而是下标从
开始还是从
开始看错。
难度:简单
题目二:斐波那契带权区间和
核心不是暴力求和,而是先推前缀和公式 。有了这个式子以后,每个询问都能转成两个前缀值的差,再配合预处理斐波那契数列就能线性扫完所有询问。
难度:中等
题目三:看看的正整数计数
这题的关键转换是:先选出哪些数字,再考虑这些数字能排成多少个不同的正整数。因为可用数字只有 ,所以预处理一个“和 + 选了几个数”的小 DP 就足够了,真正容易漏的是别把
误算成一种方案。
难度:中等
1. 三号位求和校验
问题描述
小基 正在整理一组整数序列。她只关心那些下标恰好是 的整数倍的位置。
给定一个长度为 的整数数组
,请计算所有满足下标是
的整数倍的元素之和,并判断这个和是否为
的整数倍。
输入格式
第一行输入一个整数 ,表示数组长度。
第二行输入 个整数
,表示数组元素。
输出格式
如果所求的和是 的整数倍,输出
Yes;否则输出 No。
输出大小写必须与题面一致。
样例输入
6
1 2 3 4 5 6
样例输出
Yes
| 样例 | 解释说明 |
|---|---|
| 样例1 | 下标为 Yes。 |
数据范围
题解
这题完全按题意模拟即可。
因为数组下标从 开始,所以我们只需要枚举所有位置,挑出满足:
的那些下标,把对应元素累加起来,最后判断总和是否满足:
即可。
这里唯一需要小心的是下标起点。题目里写的是 ,所以位置编号从
开始,不是从
开始。
复杂度分析
只需要扫描一遍数组。
- 时间复杂度:
- 空间复杂度:
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
def solve() -> None:
n = int(input())
arr = list(map(int, input().split()))
total = 0
# 题目下标从 1 开始,因此位置 i 对应数组下标 i - 1。
for i in range(1, n + 1):
if i % 3 == 0:
total += arr[i - 1]
print("Yes" if total % 3 == 0 else "No")
if __name__ == "__main__":
solve()
- Cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
long long total = 0;
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
// 位置编号从 1 开始,只统计 3 的倍数位置。
if (i % 3 == 0) {
total += x;
}
}
cout << (total % 3 == 0 ? "Yes" : "No") << '\n';
return 0;
}
- Java
import java.io.*;
import java.util.*;
public class Main {
static class FastScanner {
private final BufferedInputStream in = new BufferedInputStream(System.in);
private final byte[] buffer = new byte[1 << 16];
private int ptr = 0, len = 0;
private int read() throws IOException {
if (ptr >= len) {
len = in.read(buffer);
ptr = 0;
if (len <= 0) {
return -1;
}
}
return buffer[ptr++];
}
int nextInt() throws IOException {
int c;
while ((c = read()) <= ' ') {
if (c == -1) {
return -1;
}
}
int sign = 1;
if (c == '-') {
sign = -1;
c = read();
}
int val = 0;
while (c > ' ') {
val = val * 10 + (c - '0');
c = read();
}
return val * sign;
}
}
public static void main(String[] args) throws Exception {
FastScanner fs = new FastScanner();
int n = fs.nextInt();
long total = 0;
for (int i = 1; i <= n; i++) {
int x = fs.nextInt();
// 题目下标从 1 开始。
if (i % 3 == 0) {
total += x;
}
}
System.out.println(total % 3 == 0 ? "Yes" : "No");
}
}
2. 斐波那契带权区间和
问题描述
小毛在复盘一组经典递推时,定义斐波那契数列 为:
- 当
时,
- 当
时,
接着他又定义:
以及区间和:
现在有 次询问。每次给出两个整数
,请你计算:
输入格式
第一行输入一个整数 ,表示询问次数。
接下来 行,每行输入两个整数
,表示一组询问。
输出格式
输出 行,每行输出对应询问的答案。
样例输入
1
1 3
样例输出
9
| 样例 | 解释说明 |
|---|---|
| 样例1 |
数据范围
题解
如果对每个询问都直接把区间扫一遍,显然会超时。关键在于先把前缀和公式推出来。
设:
这道题有一个常用恒等式:
因此区间答案就变成:
也就是:
接下来问题就只剩一件事:快速得到所有会用到的斐波那契值。
由于题目中的 最大只有
,直接把斐波那契数列预处理到
就够了。这样每个询问只需要代一次公式,时间就是
。
为什么公式是对的
这里给一个常见的结论性写法。把:
做整理后,可以验证它满足:
而右边的闭式:
同样满足:
并且 ,所以两者恒等。
复杂度分析
设所有询问里最大的右端点是 。
- 预处理斐波那契数列的复杂度:
- 每次询问计算答案的复杂度:
- 总复杂度:
- 空间复杂度:
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
MOD = 10**9 + 7
def prefix(n: int, fib: list[int]) -> int:
if n <= 0:
return 0
# S(n) = n * F(n + 2) - F(n + 3) + 2
return (n * fib[n + 2] - fib[n + 3] + 2) % MOD
def solve() -> None:
q = int(input())
queries = []
max_r = 0
for _ in range(q):
l, r = map(int, input().split())
queries.append((l, r))
max_r = max(max_r, r)
# 需要用到 F(r + 3),因此开到 max_r + 3。
fib = [0] * (max_r + 4)
fib[1] = fib[2] = 1
for i in range(3, max_r + 4):
fib[i] = (fib[i - 1] + fib[i - 2]) % MOD
out = []
for l, r in queries:
ans = (prefix(r, fib) - prefix(l - 1, fib)) % MOD
out.append(str(ans))
sys.stdout.write("\n".join(out))
if __name__ == "__main__":
solve()
- Cpp
#include <bits/stdc++.h>
using namespace std;
static const long long MOD = 1000000007LL;
long long prefixSum(int n, const vector<long long>& fib) {
if (n <= 0) {
return 0;
}
// S(n) = n * F(n + 2) - F(n + 3) + 2
return (1LL * n * fib[n + 2] - fib[n + 3] + 2 + MOD) % MOD;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int q;
cin >> q;
vector<pair<int, int>> queries(q);
int maxR = 0;
for (int i = 0; i < q; ++i) {
int l, r;
cin >> l >> r;
queries[i] = {l, r};
maxR = max(maxR, r);
}
vector<long long> fib(maxR + 4, 0);
fib[1] = fib[2] = 1;
for (int i = 3; i <= maxR + 3; ++i) {
fib[i] = (fib[i - 1]
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

