小红书笔试 小红书秋招 0907

笔试时间:2025年9月7日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:超级重排

给定长度为 n 的数组 a,定义数组权值为所有元素之和。通过超级重排流程:

  1. 将所有元素的十进制表示按原序拼接成一个字符串
  2. 对该字符串中的所有字符进行重新排列
  3. 按照原元素的位数切分字符串,恢复为 n 个新数字

目标是找到使数组权值最大的重排方式。

输入描述

第一行输入一个整数 n(1≤n≤2×10^5),表示数组长度。 第二行输入 n 个整数a1,a2,...,an(1≤ai≤10^9)表示数组 a,题目保证每个元素的十进制表示中不含字符 '0'。

输出描述

输出一个整数,表示经过超级重排后数组的最大权值。

样例输入

2

36 15

样例输出

114

参考题解

解题思路:

  1. 记录每个数字的位数
  2. 统计所有数字字符(如[36,15]→[3,6,1,5])
  3. 计算每个位置的权重(高位权重大)
  4. 将权重从大到小排序,将数字从大到小排序
  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

参考题解

解题思路:

  1. 使用队列模拟Plog序列
  2. 每轮遍历队列,记录被评论的Plog索引
  3. 移除被评论的Plog
  4. 重复直到没有可评论的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等多种语言做法集合指南

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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