POJ 3579(二分查找差值中间值)
2016-10-25 08:29
169 查看
Median
Submit Status
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
Sample Output
Source
题目大意:给你n个数,任意两个数之间的差共有m=(n-1)*n/2种然后让你输出这些数中间的那一个,规则为
若m为奇数,中间的那一个为第(m+1)/2小的数,若m为为偶数,中间那个数指的是第m/2小的数。
思路分析:看了一下数据范围,如果用最正常最简单的做法,复杂度O(n^2),肯定会超时,因此需要采用高效率的
二分算法,因为a[i]-a[j]是取了绝对值的,因此就相当于是大的减小的,因此可以将数组a
先sort排序,然后
根据差值确定二分范围,我确定的是0~a[n-1]-a[0],然后开始二分搜索,而check函数则主要是统计比a[i]+d小的
数有多少个,如果>=(m+1)/2就return true else return false,而在统计的过程中如果用传统的顺序查找肯
定也会到致超时,所以应该使用高效率的二分查找,我直接用了upper_bound函数,统计的时候注意upper_bound-a
是所有<=a[i]+x的数组元素的个数,应该减去所有<=a[i]的元素(共i+1个)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int a
, tmp;
int judge(int x);
int n;
int main()
{
while(scanf("%d", &n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d", &a[i]);
}
sort(a,a+n);
int l=0, r=a[n-1]-a[0], ans, m=(n*(n-1))/2;
tmp=(m+1)/2;
while(l<=r)
{
int mid=(l+r)/2;
if(judge(mid))
{
r=mid-1;
ans=mid;
}
else
{
l=mid+1;
}
}
printf("%d\n",ans);
}
return 0;
}
int judge(int x)
{
int cnt=0;
for(int i=0;i<n;i++)
{
int t=upper_bound(a,a+n,a[i]+x)-a;
cnt+=(t-i-1);
}
if(cnt>=tmp)
{
return 1;
}
else
{
return 0;
}
}
Time Limit: 1000MS | Memory Limit: 65536KB | 64bit IO Format: %lld & %llu |
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
4 1 3 2 4 3 1 10 2
Sample Output
1 8
Source
题目大意:给你n个数,任意两个数之间的差共有m=(n-1)*n/2种然后让你输出这些数中间的那一个,规则为
若m为奇数,中间的那一个为第(m+1)/2小的数,若m为为偶数,中间那个数指的是第m/2小的数。
思路分析:看了一下数据范围,如果用最正常最简单的做法,复杂度O(n^2),肯定会超时,因此需要采用高效率的
二分算法,因为a[i]-a[j]是取了绝对值的,因此就相当于是大的减小的,因此可以将数组a
先sort排序,然后
根据差值确定二分范围,我确定的是0~a[n-1]-a[0],然后开始二分搜索,而check函数则主要是统计比a[i]+d小的
数有多少个,如果>=(m+1)/2就return true else return false,而在统计的过程中如果用传统的顺序查找肯
定也会到致超时,所以应该使用高效率的二分查找,我直接用了upper_bound函数,统计的时候注意upper_bound-a
是所有<=a[i]+x的数组元素的个数,应该减去所有<=a[i]的元素(共i+1个)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int a
, tmp;
int judge(int x);
int n;
int main()
{
while(scanf("%d", &n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d", &a[i]);
}
sort(a,a+n);
int l=0, r=a[n-1]-a[0], ans, m=(n*(n-1))/2;
tmp=(m+1)/2;
while(l<=r)
{
int mid=(l+r)/2;
if(judge(mid))
{
r=mid-1;
ans=mid;
}
else
{
l=mid+1;
}
}
printf("%d\n",ans);
}
return 0;
}
int judge(int x)
{
int cnt=0;
for(int i=0;i<n;i++)
{
int t=upper_bound(a,a+n,a[i]+x)-a;
cnt+=(t-i-1);
}
if(cnt>=tmp)
{
return 1;
}
else
{
return 0;
}
}
相关文章推荐
- POJ 3579 Median 查找中间值 二分
- POJ - 3579 Median(二分搜索,查找第K大的值)
- poj 3579 Median 中间值(二分搜索)
- POJ - 3579 Median (二分 + 查找第K大)
- poj 3579 Median 二分查找与lower_bound
- POJ 3579 3685(二分-查找第k大的值)
- POJ_3579_Median_(二分,查找第k大的值)
- poj 3579 Median (二分搜索之查找第k大的值)
- poj 2002 Squares 判断一些点能组成多少个正方形 二分查找
- poj 1905 Expanding Rods (二分查找)
- River Hopscotch(POJ--3258【二分查找】
- POJ 3579:Median 差值的中位数
- POJ——3061Subsequence(尺取法或二分查找)
- POJ-Prime Gap 素数筛选+二分查找
- poj 3518 Prime Gap 二分查找下界和素数筛法
- [ACM] [算法基础] POJ 4140 方程求解(二分查找)
- POJ 3903 Stock Exchange【LIS 二分查找】
- 查找(哨兵查找、二分查找、差值查找)
- Expanding Rods(POJ--1905【二分查找】
- poj_1840 Eqs(二分查找 / 哈希)