顺丰笔试 顺丰秋招 0913
笔试时间:2025年9月13日
往年笔试合集:
第一题:平衡树
小明有一个数组a,长度为n(保证n是奇数)。其中的中位数定义为:如果将这个数组排序,则最中间的那个元素即为中位数。小明每次可以选择数组中的一个数,将它加1或减1。他想知道,最少经过多少次这样的操作,可以让这个数组的中位数变成m。
输入描述
第一行一个整数T,表示数据组数。对每组数据:
- 第一行两个整数n,m,表示数组大小和期望的中位数
- 第二行n个整数a[i],表示数组初始状态
输出描述
对于每组数据,输出一行一个整数,表示答案。
样例输入
2
5 3
1 2 2 4 5
7 10
8 5 8 11 8 67 15
样例输出
1
2
对于第一组样例,把任意一个2增加1即可。
参考题解
解题思路:
- 首先对数组进行排序
- 中位数的位置固定为n/2
- 根据当前中位数与目标值m的关系:
- 如果当前中位数小于m,需要将中位数及其右边小于m的元素都调整到m
- 如果当前中位数大于m,需要将中位数及其左边大于m的元素都调整到m
- 如果相等,则不需要操作
C++:
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());
int midIndex = n / 2;
long long operations = 0;
if (a[midIndex] < m) {
for (int i = midIndex; i < n; i++) {
if (a[i] < m) {
operations += (m - a[i]);
} else {
break;
}
}
} else if (a[midIndex] > m) {
for (int i = midIndex; i >= 0; i--) {
if (a[i] > m) {
operations += (a[i] - m);
} else {
break;
}
}
}
cout << operations << "\n";
}
return 0;
}
Java:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while (T-- > 0) {
int n = sc.nextInt();
int m = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
Arrays.sort(a);
int midIndex = n / 2;
long operations = 0;
if (a[midIndex] < m) {
for (int i = midIndex; i < n; i++) {
if (a[i] < m) {
operations += (m - a[i]);
} else {
break;
}
}
} else if (a[midIndex] > m) {
for (int i = midIndex; i >= 0; i--) {
if (a[i] > m) {
operations += (a[i] - m);
} else {
break;
}
}
}
System.out.println(operations);
}
sc.close(
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025 春招笔试合集 文章被收录于专栏
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
美的集团公司福利 742人发布