• 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. }

     

  • 相关阅读:
    编译tolua——4、更新luaJit
    5_会话管理实现登录功能
    0xc000007b应用程序无法正常启动解决方案(亲测有效)
    Spring 事务一些探讨
    JVM实战:JVM运行时数据区
    仙人掌之歌——权力的游戏(1)
    unity - Blend Shape - 变形器 - 实践
    Promise小结
    loss不降低原因以及解决方法
    关于数字类型的字符串,或者double,或者integer 相除得到百分数 并四舍五入保留两位小数的通用方法
  • 原文地址:https://blog.csdn.net/GF0919/article/details/132740526