小红书笔试 小红书 0325 春招实习笔试真题

笔试时间:2026年3月25日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:乱序数据解析

题目

小红书数据库中有用户编号、用户名称和用户经验三个字段,其中:

  • 用户编号为 1 到 10^9 间的整数,且唯一;
  • 用户名称为长度不超过 10 的非空字符串,且仅由小写字母构成;
  • 用户经验为 1 到 10^9 间的浮点数。

现在,你已经获取到了 n 条用户数据,每一条用户数据由:用户编号、用户名称、用户经验三个部分组成,但顺序是混乱的。请按照:用户编号从小到大排序并将排序后的用户数据按照:用户编号、用户名称、用户经验的顺序输出。

输入描述

输入一个整数 n (1≤n≤10^5),表示用户数据的数量。此后 n 行,第 i 行依次输入以下三个部分表示第 i 条用户数据(不保证某个部分一定在前,即部分间的顺序是乱序的;各部分之间用空格分隔):

  • 一个整数 xi (1≤xi≤10^9),表示用户编号;
  • 一个长度仅由小写字母构成的字符串 si (1≤length(si)≤10),表示用户名称;
  • 一个小数位数为两位的浮点数 ci (0≤ci≤10^9),表示用户经验。

输出描述

一共 n 行,第 i 行依次输出用户编号第 i 小的用户编号、用户名称和用户经验,用空格分隔。

样例输入

3
xhs 12 106.70
0.00 abc 11
6 xhs 666.66

样例输出

6 xhs 666.66
11 abc 0.00
12 xhs 106.70

参考题解

解题思路

由于每条数据的三个字段输入顺序是随机的,但它们各自具有严格的数据类型排他性:由小写字母构成的字符串必是"用户名称",包含小数点的浮点型格式必是"用户经验",剩下的纯数字构成的必定是"用户编号"。在读入时,利用字符串首字母范围和是否包含 . 这两个特征,精准拦截并分类各个字段,将它们打包存入列表后,直接以用户编号为关键字进行升序排序并输出即可。

C++

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vector<tuple<long long, string, string>> userList;

    for (int i = 0; i < n; i++) {
        long long userId = 0;
        string userName = "", userExp = "";
        for (int j = 0; j < 3; j++) {
            string token;
            cin >> token;
            if (token[0] >= 'a' && token[0] <= 'z') {
                userName = token;
            } else if (token.find('.') != string::npos) {
                userExp = token;
            } else {
                userId = stoll(token);
            }
        }
        userList.emplace_back(userId, userName, userExp);
    }

    sort(userList.begin(), userList.end());

    for (auto& [id, name, exp] : userList) {
        cout << id << " " << name << " " << exp << "\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 n = Integer.parseInt(br.readLine().trim());

        long[] ids = new long[n];
        String[] names = new String[n];
        String[] exps = new String[n];

        for (int i = 0; i < n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < 3; j++) {
                String token = st.nextToken();
                if (token.charAt(0) >= 'a' && token.charAt(0) <= 'z') {
                    names[i] = token;
                } else if (token.contains(".")) {
                    exps[i] = token;
                } else {
                    ids[i] = Long.parseLong(token);
                }
            }
        }

        Integer[] indices = new Integer[n];
        for (int i = 0; i < n; i++) indices[i] = i;
        Arrays.sort(indices, (a, b) -> Long.compare(ids[a], ids[b]));

        StringBuilder sb = new StringBuilder();
        for (int idx : indices) {
            sb.append(ids[idx]).append(" ").append(names[idx]).append(" ").append(exps[idx]).append("\n");
        }
        System.out.print(sb);
    }
}

Python

import sys

def solve():
    input_data = sys.stdin.read().split()
    if not input_data:
        return
    n = int(input_data[0])
    idx = 1
    user_list = []
    for _ in range(n):
        user_id = 0
        user_name = ""
        user_exp = ""
        for _ in range(3):
            token = input_data[idx]
            idx += 1
            if 'a' <= token[0] <= 'z':
                user_name = token
            elif '.' in token:
                user_exp = token
            else:
                user_id = int(token)
        user_list.append((user_id, user_name, user_exp))

    user_list.sort(key=lambda user: user[0])

    out = [f"{user[0]} {user[1]} {user[2]}" for user in user_list]
    print('\n'.join(out))

if __name__ == '__main__':
    solve()

第二题:无限轮互评模拟

题目

现在有 n 条 Plog 在首页上排成一列,队尾在下侧,队头在上侧。用长度为 n 的 01 串 s=s1s2…sn 表示这条队列,其中:

  • 若 si=1,则第 i 条 Plog 属于美食;
  • 若 si=0,则第 i 条 Plog 属于旅行。

一共会进行无限轮互评操作,每一轮:

  • 所有 Plog 的拥有者同时向队头(右侧)互评;
  • 互评只会影响每条 Plog 右侧的第一个异属性 Plog,如果右侧没有异属性 Plog,则不会产生互评操作;
  • 每轮所有互评动作并行计算,然后一次性将所有已经有评论的 Plog 移出,形成新队列再进入下一轮;同一条 Plog 在一轮可能收获多条评价。

显然,无限进行下去,终究会出现不再有互评发生的情况。求整个过程中共有多少条 Plog 收获评价。

输入描述

第一行输入一个整数 n (1≤n≤10^5),表示 Plog 数量。第二行输入一个长度为 n 且只由字符 0 和 1 构成的字符串 s,表示 Plog 的属性分布,其中 si 为从左向右第 i 条 Plog 的属性。

输出描述

输出一个整数,表示所有互评结束后共有多少条 Plog 收获评价。

样例输入1

5
11101

样例输出1

2

样例说明1

在这个样例中:第一轮,第三条(1)评论第四条(0),第四条(0)评论第五条(1),共 2 条 Plog 收获评论;剩余前三条 Plog 拼接为 "111",此时剩下的全是美食 Plog,不再发生互评现象。

样例输入2

10
1100010101

样例输出2

8

样例说明2

"1100010101" → "1100" → "110" → "11"
一共有 8 条 Plog 被评论。

参考题解

解题思路

首先将连续的同属性 Plog 压缩成若干个长度块,最左侧的第一个块视为"绝对安全区",后续的块按照索引奇偶性交替扮演"异属性(敌人)"和"同属性(友军)"的角色。在从左到右遍历的过程中,将奇数索引的异属性长度不断累加,代表"挡在前面的敌人";当遇到偶数索引的同属性块时,让它与前面累积的敌人互相消耗(同属性多则余下部分并入安全区,异属性多则同属性被全部吞噬)。最终,用 Plog 总长度减去存活在安全区的总长度,就是整个过程中发生过互评(被消耗掉)的 Plog 数量。

C++

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    string s;
    cin >> s;

    if (n <= 1) {
        cout << 0 << endl;
        return 0;
    }

    // 将连续相同的字符压缩为长度块
    vector<int> blockLengths;
    char currentChar = s[0];
    int currentCount = 1;
    for (int i = 1; i < n; i++) {
        if (s[i] == currentChar) {
            currentCount++;
        } else {
            blockLengths.push_back(currentCount);
            currentChar = s[i];
            currentCount = 1;
        }
    }
    blockLengths.push_back(currentCount);

    if (blockLengths.size() <= 1) {
        cout << 0 << endl;
        return 0;
    }

    int safeCount = blockLengths[0]; // 第一块必定是安全的起始块
    int pendingEnemies = 0;          // 累积的异属性数量

    for (int i = 1; i < (int)blockLengths.size(); i++) {
        if (i % 2 != 0) {
            // 奇数索引:异属性块,敌人数量增加
            pendingEnemies += blockLengths[i];
        } else {
            // 偶数索引:同属性块,与累积的敌人发生抵消
            if (blockLengths[i] > pendingEnemies) {
                safeCount += blockLengths[i] - pendingEnemies;
                pendingEnemies = 0;
            } else {
                pendingEnemies -= blockLengths[i];
            }
        }
    }

    cout << n - safeCount << endl;
    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 n = Integer.parseInt(br.readLine().trim());
        String s = br.readLine().trim();

        if (n <= 1) {
            System.out.println(0);
            return;
        }

        // 将连续相同的字符压缩为长度块
        List<Integer> blockLengths = new ArrayList<>();
        char currentChar = s.charAt(0);
        int currentCount = 1;
        for (int

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

03-25 13:39
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务