科大讯飞笔试 科大讯飞笔试题 0720

笔试时间:2024年07月20日 提前批

历史笔试传送门:2023秋招笔试合集

第一题

题目

给出一个长度为n的序列a1,a2,a3,...an,请你按照以下规则输出序列的中位数:

1.如果序列的大小为奇数,则中位数是按照升序排序后中间的数字。

2.如果序列的大小为偶数:

  • 按照升序排序后,中间的两个数字x=y时输出任意一个即可
  • 按照升序排序后,中间的两个数字x!=y时输出min(x,y),即 x 和 y 中较小的那个数。当输出中位数 mid时,该中位数 mid从序列 a中消失,再输出消失后的序列 a’ 的中位数。

重复上述步骤,直至全部将序列 a全部输出。

输入描述

第一行输入一个正整数 n (1<= n <= 10^5)代表序列长度。

第二行输入n 个正整数代表序列元素a1,a2,a3,...an 代表序列元素。

输出描述

在一行上输出 n 个整数代表依次提取出的中位数。

样例输入一

5

4 1 8 9 5

样例输出一

5 8 1 9

样例输入二

6

6 6 6 6 6 6

样例输出二

6 6 6 6 6 6

参考题解

堆排序,使用一个有序集合维护,每次取出 s[n/2]后,删除这个数即可。

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

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class MedianFinder {
private:
    priority_queue<int> large; // 大根堆
    priority_queue<int, vector<int>, greater<int>> small; // 小根堆

public:
    MedianFinder() {}

    void addNum(int num) {
        large.push(num);
        small.push(large.top());
        large.pop();
        if (large.size() < small.size()) {
            large.push(small.top());
            small.pop();
        }
    }

    double findMedian() {
        double x = 0;
        if (small.size() < large.size()) {
            x = large.top();
            large.pop();
        } else if (small.size() == large.size()) {
            x = large.top();
            large.pop();
        }

        if (small.size() > large.size()) {
            large.push(small.top());
            small.pop();
        }

        return x;
    }
};

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

    MedianFinder mf;
    for (int i = 0; i < n; ++i) {
        mf.addNum(a[i]);
    }
    for (int i = 0; i < n; ++i) {
        cout << mf.findMedian() << " ";
    }
    cout << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    return 0;
}

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

import java.util.PriorityQueue;
import java.util.Scanner;

public class MedianFinder {
    private PriorityQueue<Integer> small; // 小根堆
    private PriorityQueue<Integer> large; // 大根堆

    public MedianFinder() {
        small = new PriorityQueue<>(); // 小根堆
        large = new PriorityQueue<>((a, b) -> b - a); // 大根堆,使用 lambda 表达式实现大根堆
    }

    public void addNum(int num) {
        large.offer(num);
        small.offer(large.poll());
        if (large.size() < small.size()) {
            large.offer(small.poll());
        }
    }

    public double findMedian() {
        double x = 0;
        if (small.size() < large.size()) {
            x = large.poll();
        } else if (small.size() == large.size()) {
            x = large.poll();
        }

        if (small.size() > large.size()) {
            large.offer(small.poll());
        }

        return x;
    }

    public static void solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = sc.nextInt();
        }

        MedianFinder mf = new MedianFinder();
        for (int x : a) {
            mf.addNum(x);
        }
        for (int i = 0; i < n; ++i) {
            System.out.print(mf.findMedian() + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        solve();
    }
}

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

import heapq
import sys
input = lambda: sys.stdin.readline().rstrip()
sint = lambda: int(input())
ints = lambda: list(map(int, input().split()))

class MedianFinder:
    def __init__(self):
        self.small = [] # 小根堆
        self.large = [] # 大根堆

    def addNum(self, num: int) -> None:
        heapq.heappush(self.large, -num)
        heapq.heappush(self.small, -heapq.heappop(self.large))
        if len(self.large) < len(self.small):
            heapq.heappush(self.large, -heapq.heappop(self.small))

    def findMedian(self) -> float:
        x = 0
        if len(self.small) < len(self.large):
            x = -self.large[0]
            heapq.heappop(self.large)
        elif len(self.small) == len(self.large):
            x = -self.large[0]
            heapq.heappop(self.large)

        if len(self.small) > len(self.large):
            heapq

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

2024 BAT笔试合集 文章被收录于专栏

持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。

全部评论

相关推荐

------------------------------------第一题题目大意:年初有&nbsp;n&nbsp;(1&nbsp;&lt;=&nbsp;n&nbsp;&lt;=&nbsp;10^6)&nbsp;本书需要整理。平时每个月能整理&nbsp;m&nbsp;(1&nbsp;&lt;=&nbsp;m&nbsp;&lt;=&nbsp;n)&nbsp;本。每年从第&nbsp;p&nbsp;(1&nbsp;&lt;=&nbsp;p&nbsp;&lt;=&nbsp;12)&nbsp;个月开始,有连续&nbsp;q&nbsp;(1&nbsp;&lt;=&nbsp;q&nbsp;&lt;=&nbsp;13-p)&nbsp;个月的忙碌期,忙碌期内每月能整理&nbsp;2*m&nbsp;本。请问整理完所有图书需要多少个月?解法思路:这是一个直接的模拟题。可以设置一个循环,按月推进。在循环中,维护当前是几月份,并根据月份判断是否处于忙碌期&nbsp;[p,&nbsp;p+q-1]&nbsp;内。根据是否忙碌,从总任务量&nbsp;n&nbsp;中减去&nbsp;m&nbsp;或&nbsp;2*m,同时月份计数器加一。当月份超过12时,重置为1,直到任务量小于等于0为止。------------------------------------第二题题目大意:一个城市有&nbsp;n&nbsp;(2&nbsp;&lt;=&nbsp;n&nbsp;&lt;=&nbsp;2e5)&nbsp;个节点,由&nbsp;n-1&nbsp;条边连接成一棵树。每个节点有一个初始安全标识:'s'(安全),&nbsp;'d'(危险),&nbsp;或&nbsp;'?'(未分类)。一个安全的网络要求任意相连的两个节点标识必须不同(只能是's'或'd')。问最少需要修改多少个节点的标识才能使整个网络变得安全。解法思路:核心是树的二分染色。因为树是二分图,我们可以将所有节点分成两个集合,使得集合内部没有边相连。通过一次图的遍历(BFS或DFS),确定每个节点的层次(奇数层或偶数层)。这样会产生两种合法的染色方案:方案A(偶数层为's',奇数层为'd')和方案B(偶数层为'd',奇数层为's')。分别计算原标识要变成这两种方案需要修改的次数,取其中的较小值即可。------------------------------------第三题题目大意:给定&nbsp;n&nbsp;(1&nbsp;&lt;=&nbsp;n&nbsp;&lt;=&nbsp;1e5)&nbsp;个道具,每个道具有一个属性值&nbsp;ai&nbsp;(1&nbsp;&lt;=&nbsp;ai&nbsp;&lt;=&nbsp;1e9)。你需要找到一个最短的连续前缀序列(从第一个道具开始),使得这个前缀序列中所有道具属性值的最小公倍数(LCM),恰好等于全部&nbsp;n&nbsp;个道具属性值的最小公倍数。输出这个最短序列的长度。(共有&nbsp;T&nbsp;组数据,&nbsp;1&nbsp;&lt;=&nbsp;T&nbsp;&lt;=&nbsp;1e4)解法思路:直接计算LCM会超出整数范围,需要转换思路。一个数的LCM由其所有质因子的最高次幂决定。首先,遍历整个数组,对每个数进行质因数分解,用一个哈希表记录下全局LCM所需要的所有质因子及其最高次幂。然后,从头开始遍历数组,同样对每个数分解质因数,用另一个哈希表维护当前前缀的质因子最高次幂。每当一个质因子在前缀中的最高次幂达到了全局要求的最高次幂时,就标记这个质因子已满足。当所有全局需要的质因子都满足时,当前的位置就是最短序列的长度。
投递科大讯飞等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
5
分享

创作者周榜

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