ACM刷题之路(十八)二分 2019暑期集训 POJ 3579 Median

简介: ACM刷题之路(十八)二分 2019暑期集训 POJ 3579 Median

题目链接:传送门

Description

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 m = 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 Input

1. 4
2. 1 3 2 4
3. 3
4. 1 10 2

Sample Output

1. 1
2. 8

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

分析:

要求差的中位数,最暴力的就是把所有的差都算出来,再sort排序,然后取中间的数输出,当然肯定超时。

我的做法是用两个二分,第一个二分中位数的值,第二个二分试探这个值的可行性

比如例子:

4

1 3 2 4

先对它排序  放入vector  然后是1 2 3 4

那么它一定有6个差  计算方法为1 + 2 + 3个差   即(1+n-1)*n/2 == (n-1)*n/2;

差的最小值假设是0,就是二分的起点s = 0 ;差一定大于0

最大值假设是a[n-1]-a[0]+1,也就是二分的终点e = 4;差一定小于最大值和最小值的差

接着先使用一次二分,找可能的中位数的值,日常  while(s<e){}   走起

第一次二分找到mid=(s+e)/2 = 2;

假设有m个差大于要求的3   :    比如1 2 3 4 5 6这样6个数  题目要求的中位数是第三个数

说明这个mid太小了,答案在mid到e的范围内,所以让s=mid;

否则,答案肯定在s到mid的范围内,让e=mid;

题目第一个例子的第一次二分,mid=2;

那么4-2    4-1   3-1 这三个差要大于等于mid值,即不满足3>3

所以答案在s=0到mid=2的范围内,以此类推,二分下去

最后二分终止时就可以找到正确答案。

但是不明白这题为什么在s=mid;或者e=mid的地方不用加1减1都可以不卡死循环

下面贴我自己手打的代码 464K 688MS

1. #include<iostream>
2. #include<algorithm>
3. #include<cstring>
4. #include<vector>
5. using namespace std;
6. vector<int>v;
7. int xiangshu, n;
8. bool dd(int x) {
9.  int sum = 0;
10.   for (int i = 0; i < n; i++) {
11.     sum += v.end() - lower_bound(v.begin(), v.end(), v[i] + x) ;
12.   }
13.   if (sum > xiangshu) return true;
14.   return false;
15. }
16. int main()
17. {
18.   int num;
19.   while (~scanf_s("%d", &n)) {
20.     v.clear();
21.     for (int i = 0; i < n; i++) {
22.       scanf_s("%d", &num);
23.       v.push_back(num);
24.     }
25.     xiangshu = n * (n - 1) / 2;
26.     if (xiangshu & 1) {
27.       xiangshu = xiangshu / 2;
28.     }
29.     else {
30.       xiangshu /= 2;
31.     }
32.     sort(v.begin(), v.end());
33.     int s = 0, e = v[n - 1] - v[0] + 1;
34.     while (s < e - 1) {
35.       int mid = (s + e) / 2;
36.       if (dd(mid)) {
37.         s = mid ;
38.       }
39.       else {
40.         e = mid;
41.       }
42.     }
43.     printf("%d\n", s);
44.   }
45.   return 0;
46. }

 


相关文章
|
存储 缓存 负载均衡
需要搭建一个高性能的文件系统?我推荐你试试它.....(上)
需要搭建一个高性能的文件系统?我推荐你试试它.....(上)
需要搭建一个高性能的文件系统?我推荐你试试它.....(上)
|
数据采集 自然语言处理 搜索推荐
图文详解 DFS 和 BFS | 算法必看系列知识二十四
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在高频面试题中。
36295 6
图文详解 DFS 和 BFS | 算法必看系列知识二十四
|
Kubernetes Linux Docker
kubelet 压力驱逐 - The node had condition:[DiskPressure]
kubelet 压力驱逐 - The node had condition:[DiskPressure]
1791 0
|
机器学习/深度学习 TensorFlow 算法框架/工具
【大作业-04】手把手教你构建垃圾分类系统-基于tensorflow2.3
本文介绍了基于TensorFlow 2.3的垃圾分类系统,通过B站视频和博客详细讲解了系统的构建过程。系统使用了包含8万张图片、245个类别的数据集,训练了LeNet和MobileNet两个卷积神经网络模型,并通过PyQt5构建了图形化界面,用户上传图片后,系统能识别垃圾的具体种类。此外,还提供了模型和数据集的下载链接,方便读者复现实验。垃圾分类对于提高资源利用率、减少环境污染具有重要意义。
643 0
【大作业-04】手把手教你构建垃圾分类系统-基于tensorflow2.3
|
存储 开发框架 前端开发
在Vue&Element前端项目中,对于字典列表的显示处理
在Vue&Element前端项目中,对于字典列表的显示处理
|
自然语言处理 Linux iOS开发
【推荐】博客创作必备工具✨
为了帮助博主们更高效地创作和发布内容,本文汇总了从 Markdown 编辑器、截图工具、绘图工具到发布工具的写博客必备工具。这些工具涵盖了文本编辑、图片处理、图表绘制、GIF 录制和多平台发布等多个方面。无论你是初学者还是经验丰富的创作者,这些工具都会为你提供全方位的支持,助力你轻松高效地完成博客创作和发布。
479 64
|
数据采集 自然语言处理 文字识别
92页的llama 3.1技术报告,我替你们啃下来了
作者花了半个月时间,认真读完了llama 3.1技术报告,并总结成本文,希望能帮到对这个感兴趣的小伙伴们。
92页的llama 3.1技术报告,我替你们啃下来了
|
JavaScript 前端开发
JavaScript while 循环
JavaScript while 循环
201 3
|
前端开发
HTML|利用CSS美化一个html表格
HTML|利用CSS美化一个html表格
665 0