【笔试刷题】小红书-2026.03.08-改编真题
✅ 春招备战指南 ✅
💡 学习建议:
- 先尝试独立解题
- 对照解析查漏补缺
🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。
🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力
🌸 目前本专栏已经上线200+套真题改编解析,后续会持续更新的
春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗
小红书-2026.03.08
整体难度更贴近 Mid / Mid / High。第二题容易误入区间 DP,第三题最容易错在“只顾计数,不顾删除后的相对顺序”。
题目一:完美数字
这题先别急着对每个询问现算。因为上界只有 ,长度至少为
的连续乘积其实没多少个,直接一次性预处理出来反而最稳。
难度:Mid
题目二:强迫症
这题看起来是在字符串上做区间翻转,真正决定答案的却不是区间本身,而是哪几对对称位置不一样。把这些位置压成左半边的若干连续块,答案就直接出来了。
难度:Mid
题目三:每日一题 Plus
这题表面是在删字符,第一步确实要先求“每个字母最多保留多少个”;但只做到这一步还不够,因为删除后的答案必须保持原串相对顺序。最终还要再做一遍按配额取子序列的字典序最小化。
难度:High
01. 完美数字
问题描述
本题是小红书 2025.08.27 第 1 题的原题。
用户的每一次点赞都代表着对内容的喜爱。小红定义一个正整数 为完美数字,当且仅当同时满足以下两个条件:
-
可以将
写作一个公差为
且所有元素都是正整数的等差数列的乘积,例如,
可以写作
;
-
上述等差数列的长度至少为
。
现在小红薯接收到多次 点赞数查询,每次给出一个正整数
,请帮助小红薯判断该点赞数是否为完美数字。
输入格式
每个测试文件均包含多组测试数据。第一行输入一个整数 代表数据组数。
接下来每组测试数据输入一行,一个整数 ,表示一次点赞数查询。
输出格式
对于每组测试数据,新起一行,如果点赞数是完美数字,输出 YES;否则,输出 NO。
样例输入
3
6
2
24
样例输出
YES
NO
YES
数据范围
题解
这题如果对每个询问都临时去试所有长度和起点,思路当然也能写,但完全没有必要。真正该抓住的是上界:,满足条件的连续乘积总数其实非常少,完全可以一次性预处理出来。
设一个完美数字写成:
其中 ,
。
先看长度上界。若 ,最小乘积都已经是:
所以合法长度只可能在 之间,长度范围一下子就被压得很小了。
接着枚举每个长度 的起点
。因为乘积会随着
的增大快速变大,所以一旦某个起点已经越界,后面的起点也不用再试。这样预处理下来,所有可能的完美数字只有很少一批,直接塞进哈希表即可。
之后每次询问只需要判断这个数在不在集合里,单次复杂度就是 。
复杂度方面:
-
预处理总规模很小,可以认为是常数级。
-
每次查询时间复杂度是
。
参考代码
- Python
import sys
input = lambda: sys.stdin.readline().strip()
LIM = 10 ** 9
good = set()
for ln in range(3, 13):
st = 1
while True:
prod = 1
overflow = False
for i in range(ln):
value = st + i
# 先判断这一步乘上去会不会越界。
if prod > LIM // value:
overflow = True
break
prod *= value
# 一旦当前起点已经越界,后面的起点只会更大。
if overflow:
break
good.add(prod)
st += 1
t = int(input())
for _ in range(t):
x = int(input())
# 预处理后,每次询问只要查集合。
print("YES" if x in good else "NO")
- Cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
const long long lim = 1000000000LL;
unordered_set<long long> good;
for (int len = 3; len <= 12; ++len) {
for (long long st = 1; ; ++st) {
long long prod = 1;
bool overflow = false;
for (int i = 0; i < len; ++i) {
long long value = st + i;
// 这一位乘上去会越界,就可以直接停。
if (prod > lim / value) {
overflow = true;
break;
}
prod *= value;
}
// 当前起点已经越界,后面的起点也不用再试。
if (overflow) {
break;
}
good.insert(prod);
}
}
int t;
cin >> t;
while (t--) {
long long x;
cin >> x;
// 预处理后,单次查询就是 O(1) 查表。
cout << (good.count(x) ? "YES" : "NO") << '\n';
}
return 0;
}
- Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
final long lim = 1000000000L;
Set<Long> good = new HashSet<>();
for (int len = 3; len <= 12; len++) {
for (long st = 1; ; st++) {
long prod = 1;
boolean overflow = false;
for (int i = 0; i < len; i++) {
long value = st + i;
// 这一位乘上去会越界,就可以直接停。
if (prod > lim / value) {
overflow = true;
break;
}
prod *= value;
}
// 当前起点已经越界,后面的起点也不用再试。
if (overflow) {
break;
}
good.add(prod);
}
}
int t = Integer.parseInt(br.readLine());
StringBuilder ans = new StringBuilder();
while (t-- > 0) {
long x = Long.parseLong(br.readLine());
// 预处理后,单次查询就是查集合。
ans.append(good.contains(x) ? "YES" : "NO").append('\n');
}
System.out.print(ans);
}
}
02. 强迫症
问题描述
本题是小红书 2025.08.20 第 2 题的原题。
在小红书首页的两列
中,小红薯独爱第一列。她将第一列每条
的点赞状态从上到下用一个二进制字符串
表示,其中:
- 字符
表示用户已点赞第
条
;
- 字符
表示用户未点赞第
条
。
小红薯定义一轮点赞行为如下:
- 选择索引对
;
- 从第
条
开始,到第
条
结束,进行一次重复点赞行为。这会使得原本未点赞的
变为已点赞,原本已点赞的
变为未点赞。
小红薯希望使得这一列的点赞状态调整为一个回文串,即第一条和最后一条
的点赞状态相同,第二条和倒数第二条
的点赞状态相同,以此类推。
请计算她最少需要进行的点赞行为轮数。
输入格式
每个测试文件均包含多组测试数据。第一行输入一个整数代表数据组数,每组测试数据描述如下:
第一行输入一个整数,表示
数量;
第二行输入一个长度为、由字符
0和1构成的字符串,表示点赞状态。
除此之外,保证单个测试文件的之和不超过
。
输出格式
对于每一组测试数据,新起一行,输出一个整数,代表使字符串成为回文串所需的最少点赞行为轮数。
样例输入
2
2
01
3
010
样例输出
1
0
数据范围
- 单个测试文件中所有
之和不超过
题解
这题看起来像是在一个二进制串上做区间翻转,但真正要盯住的不是整段字符串,而是每一对对称位置。
对于位置 和位置
:
-
如果二者本来就相同,那这一对不用管。
-
如果二者不同,那这一对迟早要被修好。
于是可以把所有不相等的对称位置单独拎出来。设这些位置对在左半边的下标分别是:
如果翻转一个区间 ,那么某一对对称位置只有在“恰好翻到其中一个端点”时,是否相等的状态才会改变。进一步观察会发现:一次操作所影响到的这些对称下标,在左半边一定对应一段连续区间。
反过来,如果左半边有一段连续的不相等下标,比如从 到
,那么直接翻转左半边这个区间
,就能一次性把这整段对应的对称关系全部翻转,而不会影响其他位置对。
所以答案就非常直接了:
把所有不相等的对称位置找出来,统计它们在左半边形成了多少段连续块,答案就是多少。
这也是为
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力
