淘天笔试 淘天笔试题 0329

笔试时间:2025年03月29日

历史笔试传送门:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

题目:合并代价

小红拿到一个长度为n的数组,下标从1开始。定义一次合井操作为:选定任意的两个相邻的元素ai和ai+1,将它们合并成一个数,其余元素按照原有顺序从前到后依次拼接。这个数等于ai和ai+1的最大值,数组长度减少1。

例如a=[1,2,3,4,5],小红可以选定a2和a3,合并成3,数组变为[1,3,4,5],花费代价3。在执行上述的合并操作前,小红可以选择任意两个元索,将它们交换任意次(也可以不交换)。求解,执行恰好n-1轮"合并"操作,使得将数组合并的只剩一个数,最少需要花费多少代价?

输入描述

第一行输入一个整数n,表示数组长度。

第二行输入n个整数a1,a2,..an代表数组元素。

输出描述

输出一个整数,表示最小花费。

样例输入

3

3 2 1

样例输出

5

说明:

在这个样例中,有两种直接合并的方法:

1、先合并3,2,花费max{3,2}=3;再合井{3,1},花费max{3,1}=3,总花费6。

2、先合并2,1,花费max{2,1}=1;再合幷{3,2},花费max{3,2}=3,总花费5。

然而,不要忘记了,在开始前。我们还可以进行交换操作。然而,可以证明,再怎么交换也不会存在比5更小的答案。

参考题解

由于可以在操作之前进行任意次交换,那么问题其实就转化成了类似哈夫曼树问题。用一个优先队列维护所有元素,每次取出最小的两个数,把他们中较大的那个重新入队并加到答案中,直到只剩最后一个数。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <bits/stdc++.h>
usingnamespacestd;
using ll = longlong;
int main() {
    int n;
    cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    priority_queue<ll, vector<ll>, greater<ll>> q;
    for (auto& x : a) {
        q.push(x);
    }
    ll res = 0;
    while (q.size() > 1) {
        ll x = q.top(); q.pop();
        ll y = q.top(); q.pop();
        res += max(x, y);
        q.push(max(x, y));
    }
    cout << res << endl;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextLong();
        }

        PriorityQueue<Long> q = new PriorityQueue<>(Comparator.naturalOrder());
        for (long x : a) {
            q.add(x);
        }

        long res = 0;
        while (q.size() > 1) {
            long x = q.poll();
            long y = q.poll();
            res += Math.max(x, y);
            q.add(Math.max(x, y));
        }

        System.out.println(res);
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

import heapq

def main():
    n = int(input())
    a = list(map(int, input().split()))
    
    q = []
    for x in a:
        heapq.heappush(q, x)
    
    res = 0
    while len(q) > 1:
        x = heapq.heappop(q)
        y = heapq.heappop(q)
        res += max(x, y)
        heapq.heappush(q, max(x, y))
    
    print(res)

if __name__ == "__main__":
    main()

第二题

题目:最少修改次数

小苯有一个长度为n的01串x(下标从1到n),巧合的是格格也有一个长度恰好为n-1的01串y。(下标从1到n-1)

据说,格格的字符串y是用来匹配小菜的字符串x的,具体来说:

如果yi = 1 (1 ≤ i ≤ n - 1),则意味着必须有:xi ≠ xi+1

如果yi = 0 (1 ≤ i ≤ n - 1),则意味着必须有:xi = xi+1

而现在小菜的串并不一定满足y串的匹配要求,因此格格希望小菜修改尽可能少的字符,使得匹配成立,调你帮小菜算一算至少需要修改多少个字符吧。

修改:选择i (1 ≤ i ≤ n),执行:xi := xi ⊕ 1。(其中⊕表示按位异或或运算。)

输入描述

每个测试文件均包含多组测试数据。第一行输入一个整数T (1 ≤ T ≤ 100) 代表数据组数,

每组测试数据描述如下:第一行输入一个正整数n (2 ≤ n ≤ 10^6) 代表x串的长度。

第二行输入一个长度为n,仅由字符'0'和'1'构成的字符串x。

第三行输入一个长度为n-1,仅由字符'0'和'1'构成的字符串y。

除此之外,保证单个测试文件的n之和不超过10^6。

输出描述

对于每组测试数据在单独的一行输出一个整数,表示最少的修改次数。

样例输入

2

8

11001011

1000111

6

101010

11111

样例输出

4

0

说明:

对于第一组测试数据,我们修改x串为"10000101"即可,需要至少4次修改操作。

对于第二组测试数据,我们不需要修改x,因此输出0即可。

参考题解

除第一个位置外,x的每一项都受到y对应位置的影响。确切来说只要决定了x的第一位,那么后面的所有位置都能依次确定。因此做法就是枚举x的第一位是0还是1,进而计算出总花费,两种情况取最小即可。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <bits/stdc++.h>
usingnamespacestd;
int calc(vector<int> x, string& y, int st) {
    int res = 0;
    int n = y.size();
    if (x[0] != st) {
        res++;
        x[0] ^= 1;
    }
    for (int i = 0; i < n; i++) {
        if (y[i] == '1') {
            if (x[i + 1] == x[i]) {
                x[i + 1] ^= 1;
                res++;
            }
        } else {
            if (x[i + 1] != x[i]) {
                x[i + 1] ^= 1;
                res++;
            }
        }
    }
    return res;
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        string z, y;
        cin >> z >> y;
        vector<int> x;
        for (char ch : z) {
           

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

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

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

全部评论

相关推荐

1.自我介绍2.实习拷打3.mq如何能解决流量毛刺问题的4.mq如何实现数据从客户端到broker集群的5.mq发数据是用了什么协议,是怎么保证不丢数据的6.tcp是如何建立连接的,socket只是表层表现,底层原理呢7.broker集群是如何保证exactly&nbsp;one语义的8.broker集群是如何保证不丢数据的9.一个topic下有多个broker的实例,如果一个主broker挂了,是怎么切换的10.通过ISR水位线就能保证数据不丢失吗11.ack除了0,1,-1三种不同的确认的方式,如果想要保证数据不丢失,你能另外考虑比较好的实现方式吗12.wal为啥会有这种策略,为啥要先写日志呢13.broker是如何把message持久化的14.零拷贝是什么东西15.零拷贝和mmap还有sendfile关系是什么16.零拷贝解决了什么核心问题17.那你觉得为啥要有内核态和用户态区分呢18.操作系统是如何实现对内核态和用户态的区分19.你觉得可能是在页表上实现,那现在请完整考虑3种需要:1.感知到还没被分配的内存空间大小&nbsp;2.申请满足需要的内存空间&nbsp;3.用户态程序没法申请内核态的空间&nbsp;假如你要设计并且实现这样的一个系统,你会如何实现呢20.页表的是解决什么问题21.页表最大能存多少页,每页大小是多少22.分页和分段有啥区别呢23.为啥分段会有内部碎片的问题,但是分页没有呢,你说分页大小小,分段也可以分段的很小也是几KB啊,那是为什么呢24.二级页表是解决什么问题的,它的原理是怎么样的25.讲讲java的gc26.图用什么数据结构存27.想要遍历图的所有节点如何遍历28.讲讲非递归遍历代码怎么写
查看28道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务