小红书笔试 小红书秋招 0907
笔试时间:2025年9月7日
往年笔试合集:
第一题:超级重排
给定长度为 n 的数组 a,定义数组权值为所有元素之和。通过超级重排流程:
- 将所有元素的十进制表示按原序拼接成一个字符串
- 对该字符串中的所有字符进行重新排列
- 按照原元素的位数切分字符串,恢复为 n 个新数字
目标是找到使数组权值最大的重排方式。
输入描述
第一行输入一个整数 n(1≤n≤2×10^5),表示数组长度。 第二行输入 n 个整数a1,a2,...,an(1≤ai≤10^9)表示数组 a,题目保证每个元素的十进制表示中不含字符 '0'。
输出描述
输出一个整数,表示经过超级重排后数组的最大权值。
样例输入
2
36 15
样例输出
114
参考题解
解题思路:
- 记录每个数字的位数
- 统计所有数字字符(如[36,15]→[3,6,1,5])
- 计算每个位置的权重(高位权重大)
- 将权重从大到小排序,将数字从大到小排序
- 贪心分配:最大数字放到最大权重位置
C++:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int maxL = 0;
vector<int> len_cnt(11, 0);
vector<int> digit_cnt(10, 0);
for (int i = 0; i < n; i++) {
string tok;
cin >> tok;
int L = tok.length();
len_cnt[L]++;
maxL = max(maxL, L);
for (char ch : tok) {
int d = ch - '0';
digit_cnt[d]++;
}
}
vector<int> suff_ge(maxL + 2, 0);
int s = 0;
for (int L = maxL; L >= 1; L--) {
s += len_cnt[L];
suff_ge[L] = s;
}
vector<long long> pow10(maxL);
pow10[0] = 1;
for (int e = 1; e < maxL; e++) {
pow10[e] = pow10[e - 1] * 10;
}
long long ans = 0;
int d = 9;
for (int e = maxL - 1; e >= 0; e--) {
int slots = suff_ge[e + 1];
while (slots > 0) {
if (digit_cnt[d] == 0) {
d--;
continue;
}
int take = min(digit_cnt[d], slots);
ans += (long long)take * d * pow10[e];
digit_cnt[d] -= take;
slots -= take;
}
}
cout << ans << endl;
return 0;
}
Java:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int maxL = 0;
int[] lenCnt = new int[11];
int[] digitCnt = new int[10];
for (int i = 0; i < n; i++) {
String tok = sc.next();
int L = tok.length();
lenCnt[L]++;
maxL = Math.max(maxL, L);
for (char ch : tok.toCharArray()) {
int d = ch - '0';
digitCnt[d]++;
}
}
int[] suffGe = new int[maxL + 2];
int s = 0;
for (int L = maxL; L >= 1; L--) {
s += lenCnt[L];
suffGe[L] = s;
}
long[] pow10 = new long[maxL];
pow10[0] = 1;
for (int e = 1; e < maxL; e++) {
pow10[e] = pow10[e - 1] * 10;
}
long ans = 0;
int d = 9;
for (int e = maxL - 1; e >= 0; e--) {
int slots = suffGe[e + 1];
while (slots > 0) {
if (digitCnt[d] == 0) {
d--;
continue;
}
int take = Math.min(digitCnt[d], slots);
ans += (long)take * d * pow10[e];
digitCnt[d] -= take;
slots -= take;
}
}
System.out.println(ans);
}
}
Python:
def main():
n = int(input())
tokens = input().split()
maxL = 0
len_cnt = [0] * 11
digit_cnt = [0] * 10
for tok in tokens:
L = len(tok)
len_cnt[L] += 1
if L > maxL:
maxL = L
for ch in tok:
d = int(ch)
digit_cnt[d] += 1
suff_ge = [0] * (maxL + 2)
s = 0
for L in range(maxL, 0, -1):
s += len_cnt[L]
suff_ge[L] = s
pow10 = [1] * maxL
for e in range(1, maxL):
pow10[e] = pow10[e - 1] * 10
ans = 0
d = 9
for e in range(maxL - 1, -1, -1):
slots = suff_ge[e + 1]
while slots > 0:
if digit_cnt[d] == 0:
d -= 1
continue
take = min(digit_cnt[d], slots)
ans += take * d * pow10[e]
digit_cnt[d] -= take
slots -= take
print(ans)
main()
第二题:排队进行
n条Plog排成一列,用01串表示(1表示美食,0表示旅行)。进行无限轮互评操作,每轮所有Plog同时向队头互评,只影响右侧第一个异属性Plog。被评论的Plog会被移出队列。求总共有多少条Plog收获评价。
输入描述
第一行输入一个整数 n (1 ≤ n ≤ 10^5),表示 Plog 数量。 第二行输入一个长度为 n 且只由字符 '0' 和 '1' 构成的字符串 s。
输出描述
输出一个整数,表示所有互评结束后共有多少条 Plog 收获评价。
样例输入
5
11101
样例输出
2
参考题解
解题思路:
- 使用队列模拟Plog序列
- 每轮遍历队列,记录被评论的Plog索引
- 移除被评论的Plog
- 重复直到没有可评论的Plog
C++:
#include <iostream>
#include <deque>
#include <vector>
#include <string>
using namespace std;
int main() {
int n;
string s;
cin >> n >> s;
deque<char> dq;
for (char c : s) {
dq.push_back(c);
}
int res = 0;
while (!dq.empty()) {
vector<int> toRemove;
for (int i = 0; i < dq.size() - 1; i++) {
if (dq[i] != dq[i + 1]) {
toRemove.push_back(i + 1);
}
}
if (toRemove.empty()) break;
res += toRemove.size();
for (int i = toRemove.size() - 1; i >= 0; i--) {
dq.erase(dq.begin() + toRemove[i]);
}
}
cout << res << endl;
return 0;
}
Java:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n =
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025 春招笔试合集 文章被收录于专栏
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
查看12道真题和解析