B站笔试 B站笔试题 bilibili 0518

笔试时间:2025年5月18日

第一题:对称数组

小红有一个数组,她每次可以让两个相邻的数字一起加一,她想知道把数组变成左右对称的最小操作次数。

左右对称的意思是将数组整体翻转后与原数组一致,例如:{1,2,3,3,2,1},{4,0,4}都是左右对称的,而{8,1,0,9,7,5},{9,2,2,7,6,8}都不是左右对称的。

输入描述

第一行输入一个整数 n(1 ≤n ≤ 2* 10^5),表示数组长度。

第二行输入n 个整数 a¡ (0 ≤ a¡≤ 10^9)表示数组。

输出描述

输出一个整数表示将数组变成左右对称的最小操作次数,若无法变成左右对称,则输出-1.

样例输入

5

1 1 2 2 1

样例输出

1

说明:将第二个元素和第三个元素加一即可,{1,1+1 2+1,2,1} -> {1,2,3,2,1}。

参考题解

要将数组变成左右对称,我们需要确保数组中的元素满足 a[i] + a[n-1-i] 对于所有 i 从 0 到 n/2-1 都相等。每次操作可以选择两个相邻的元素同时加1,这会影响对称位置上的元素。关键在于如何通过这些操作调整对称位置上的元素之和。

检查可行性:首先,我们需要检查是否可以通过操作使得所有对称位置的和相等。具体来说,对于对称位置 (i, j)(其中 j = n-1-i),如果 i < j,那么这些位置的和必须满足一定的条件。特别是,对于相邻的对称对,比如 (i, i+1) 和 (j-1, j),操作会影响这些对称对的和。但经过分析,可以发现,只要对称位置的和的差是偶数,就有可能通过操作调整。

计算操作次数:对于每个对称对 (i, j),我们需要确定它们的和应该等于某个目标值。这个目标值通常由中间对称对决定。例如,对于数组长度为奇数的情况,中间元素可以单独处理。然后,通过贪心的方式,从外向内或从内向外调整对称对的和,确保每次操作都能有效减少差异。

贪心调整:从数组的两端向中间处理。对于每个对称对 (i, j),计算当前和与目标和的差。如果当前和小于目标和,需要通过操作来增加和;反之,则无法调整,直接返回-1。操作次数可以通过计算差值的绝对值来确定。

C++:

// C++ 版本
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

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

    int n;
    cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    ll res = 0;
    bool possible = true;
    int left = 0, right = n - 1;

    while (left < right) {
        if (a[left] != a[right]) {
            if (left + 1 == right) {
                possible = false;
                break;
            }
            ll diff = a[left] - a[right];
            if (diff > 0) {
                // 增加 left+1 处
                a[left + 1] += diff;
                res += diff;
            } else {
                // diff < 0, 增加 right-1 处
                a[right - 1] += -diff;
                res += -diff;
            }
            // 使两端相等
            a[left] = a[right];
        }
        left++;
        right--;
    }

    if (possible) {
        cout << res << "\n";
    } else {
        cout << -1 << "\n";
    }
    return 0;
}

Java:

// Java 版本
import java.io.*;
import java.util.*;

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());
        StringTokenizer st = new StringTokenizer(br.readLine());
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = Long.parseLong(st.nextToken());
        }

        long res = 0;
        boolean possible = true;
        int left = 0, right = n - 1;

        while (left < right) {
            if (a[left] != a[right]) {
                if (left + 1 == right) {
                    possible = false;
                    break;
                }
                long diff = a[left] - a[right];
                if (diff > 0) {
                    // 增加 left+1 处
                    a[left + 1] += diff;
                    res += diff;
                } else {
                    // diff < 0, 增加 right-1 处
                    a[right - 1] += -diff;
                    res += -diff;
                }
                // 使两端相等
                a[left] = a[right];
            }
            left++;
            right--;
        }

        System.out.println(possible ? res : -1);
    }
}

Python:

n = int(input())
a = list(map(int, input().split()))
res = 0
possible = True

left = 0
right = n - 1

while left < right:
    if a[left] != a[right]:
        if left + 1 == right:
            possible = False
            break
        diff = a[left] - a[right]
        if diff > 0:
            a[left + 1] += diff
            res += diff
        else:
            a[right - 1] += -diff
            res += -diff
        a[left] = a[right]
    left += 1
    right -= 1

if possible:
    print(res)
else:
    print(-1)

第二题:区间和

给出一个长度为n的序列a1,a2,…,n,求取出k个不同的区间,要求满足取出

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

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

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

全部评论

相关推荐

05-24 12:03
湖南大学 Java
1、项目什么时候会触发失败,人为介入;2、sql如何分页展示&nbsp;&nbsp;&nbsp;&nbsp;在sql中,可以使用limit和offset子句或者row_number()窗口参数来实现分页展示数据;&nbsp;limit&nbsp;number_of_rows表示每页展示的行数,offset&nbsp;offset_value表示跳过前面的行数。例如,对于第一页,offset是0,以此类推;3、http包含了哪些内容&nbsp;&nbsp;&nbsp;&nbsp;请求方式(get、post、delete、put)、状态码(1XX表示请求已被服务器接收,继续处理、2XX表示请求已成功被服务器接收、理解、并接受、3XX表示需要客户端采取进一步的操作才能完成请求、4XX表示客户端请求有语法错误或无法完成请求、5XX表示服务器在处理请求的过程中发生了错误)4、TCP的状态&nbsp;&nbsp;&nbsp;&nbsp;三次握手、四次挥手5、如果在建立连接的时候,ack后,开始发送数据,但是ack数据包丢失,这个情况下服务器如何处理这个数据包&nbsp;&nbsp;&nbsp;&nbsp;首先关于服务器状态的改变,在正常情况下,服务器收到客户端的ACK报文之后,连接就进入了ESTABLISHED(已建立)状态,但是ACK数据包丢失,服务器在发送SYN-ACK报文之后,会等待客户端ACK的确认,此时服务器的状态会一直保持在SYN-RCVD(同步已接受)状态。&nbsp;&nbsp;&nbsp;&nbsp;服务器的重传机制,在一定时间内,没有收到客户端的ACK报文,服务器会重新发送SYN-ACK报文。&nbsp;&nbsp;&nbsp;&nbsp;在等待ACK的过程中,服务器会为这个半连接分配一定资源。6、操作系统的进程调度方式,win使用哪些进程调度方式,linux是使用哪些进程调度方式操作系统的进程调度方式主要有以下几种:先来先服务调度算法(FCFS)原理&nbsp;:按照进程进入就绪队列的先后顺序进行调度,先到达的进程先得到处理。特点&nbsp;:简单易懂,但可能导致后到达的短进程等待过长。短进程优先调度算法(SJF)原理&nbsp;:优先调度估计运行时间短的进程。特点&nbsp;:能有效减少进程的平均等待时间,但难以准确预估进程的运行时间。时间片轮转调度算法(RR)原理&nbsp;:将&nbsp;CPU&nbsp;时间划分为一个个时间片,按就绪队列顺序分配时间片给进程运行,若时间片用完而进程未完成,则进入队列等待下一轮调度。特点&nbsp;:适合多用户分时系统,保证了每个进程都能获得一定的&nbsp;CPU&nbsp;时间,但时间片大小的选择较关键。优先级调度算法原理&nbsp;:为每个进程设置优先级,优先级高的进程先调度,优先级相同则按先来先服务调度。特点&nbsp;:灵活但易导致低优先级进程饥饿。多级反馈队列调度算法原理&nbsp;:设置多个就绪队列,每个队列对应一个优先级和时间片大小,进程根据运行时间和抢占情况在不同队列间移动,优先级高的队列中的进程先调度,同一队列中的进程采用时间片轮转调度。特点&nbsp;:兼顾多个方面,是较复杂的调度算法,能有效处理各种类型的进程。Windows&nbsp;的进程调度方式:多优先级反馈调度算法&nbsp;:Windows&nbsp;将进程分为多个优先级,优先级高的进程优先调度。系统会根据进程的行为动态调整优先级,如交互式进程的优先级会提高,CPU&nbsp;密集型进程的优先级会降低。实时进程调度&nbsp;:对于实时进程,Windows&nbsp;使用先来先服务和轮转算法,确保实时任务及时得到处理。Linux&nbsp;的进程调度方式:完全公平调度器(CFS)&nbsp;:基于红黑树数据结构管理进程,通过计算进程的虚拟运行时间来确定调度顺序,优先调度虚拟运行时间少的进程,兼顾进程的公平性和吞吐量。实时进程调度&nbsp;:包括先来先服务(SCHED_FIFO)和轮转(SCHED_RR)两种策略,确保实时进程及时得到&nbsp;CPU&nbsp;资源。过时的&nbsp;O(1)调度算法&nbsp;:早期&nbsp;Linux&nbsp;使用,基于就绪队列和过期队列,优先调度优先级高的进程。pv操作PV&nbsp;操作是操作系统中进程同步与互斥的一种重要机制,主要用于处理进程之间的资源竞争和同步问题。PV&nbsp;操作通过信号量(semaphore)来实现,它包含两种操作:P&nbsp;操作和&nbsp;V&nbsp;操作。PV&nbsp;操作的定义P&nbsp;操作(wait&nbsp;操作)&nbsp;:用于测试信号量的值。若信号量的值大于等于&nbsp;1,则信号量减&nbsp;1,进程继续执行;若信号量的值小于&nbsp;0,则进程进入等待队列等待。P&nbsp;操作的格式如下:V&nbsp;操作(signal&nbsp;操作)&nbsp;:用于将信号量的值加&nbsp;1。若信号量的值大于等于&nbsp;0,则直接加&nbsp;1;若信号量的值小于&nbsp;0,表示有进程在等待该信号量,此时唤醒一个等待的进程,并将信号量的值加&nbsp;1。V&nbsp;操作的格式如下:
查看7道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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