• L - Median


    Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numbers: ∣Xi - Xj∣ (1 ≤ i  j  N). We can get C(N,2) differences through this work, and now your task is to find the median of the differences as quickly as you can!

    Note in this problem, the median is defined as the (m/2)-th  smallest number if m,the amount of the differences, is even. For example, you have to find the third smallest one in the case of = 6.

    Input

    The input consists of several test cases.
    In each test case, N will be given in the first line. Then N numbers are given, representing X1, X2, ... , XN, ( Xi ≤ 1,000,000,000  3 ≤ N ≤ 1,00,000 )

    Output

    For each test case, output the median in a separate line.

    Sample

    InputcopyOutputcopy
    4
    1 3 2 4
    3
    1 10 2
    
    1
    8

    题意:每一组数据给一个n,后面给n个数,求这些数之间的差绝对值的中位数,比如例子1 3 2 4 ,差为1,1,1,2,2,3,如果个数为偶数则取中间前面,奇数取中间的数。

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<map>
    4. #include<cstring>
    5. #include<vector>
    6. #include<cmath>
    7. #include<cstdlib>
    8. using namespace std;
    9. const int N = 1e6 + 10;
    10. vector<int> vv;
    11. int n, cha;
    12. //n是输入数的个数,cha是这些数的差的个数
    13. //41 3 2 41+2+3个,等差公式:cha = (0+n-1)*n/2;
    14. int find(int x)
    15. {
    16. int sum = 0;
    17. // 使用二分查找在有序向量v中找到第一个大于等于v[i]+x的位置
    18. // 然后用向量末尾迭代器减去该位置迭代器,得到大于等于v[i]+x的元素个数
    19. for (int i = 0; i < n; i++) sum += vv.end()-lower_bound(vv.begin(), vv.end(), vv[i] + x);
    20. //为什么sum>cha,如果当前mid的差值都大于cha了,那还有l到mid之间的数没有考虑
    21. //如x = 2,cha = 3,sum = 4,说明在差的序列中有42,而且差值为02还没考虑,显然2就不是我们要找的数了,应该在02中去找
    22. if (sum > cha) return 1; //注:不能等于,道理同上
    23. else return 0;
    24. }
    25. int main()
    26. {
    27. while (cin >> n)
    28. {
    29. vv.clear();
    30. for (int i = 0; i < n; i++)
    31. {
    32. int num; scanf_s("%d", &num);
    33. vv.push_back(num);
    34. }
    35. sort(vv.begin(), vv.end());
    36. cha = (n - 1) * n / 2;
    37. cha /= 2;
    38. int l = 0, r = vv[n - 1] - vv[0] + 1;
    39. //差值的最小为0,最大为数组中最大与最小的数的差加一
    40. //每次进行二分,如果二分得到的差值(设为x),如果存在与当前的数(设为v[i])的个数(即v[i]+x)大于我们要找的位置,则在mid和r之间,都在在l和mid之间
    41. //差值越大数越少,差值越小数越多
    42. while (l < r)
    43. {
    44. int mid = (l + r + 1) / 2;
    45. if (find(mid))l = mid;
    46. else r = mid-1;
    47. }
    48. cout << l << endl;
    49. }
    50. }

     

  • 相关阅读:
    线段树【java实现】
    《深入浅出C++》——初识C++
    多模态大语言模型综述
    基于风驱动优化的BP神经网络(分类应用) - 附代码
    Redis数据结构之ziplist
    正点原子嵌入式linux驱动开发——Linux RTC驱动
    国产AI作画神器火了,更懂中文,竟然还能做周边!
    滚动条不占位置
    Flutter最新配置本地资源文件详解,报错看这篇文章就对了!
    删除事件...
  • 原文地址:https://blog.csdn.net/GF0919/article/details/132740526