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

4
1 3 2 4
3
1 10 2

Sample Output

1
8

Source

field=source&key=POJ+Founder+Monthly+Contest+%E2%80%93+2008.04.13">POJ Founder Monthly Contest – 2008.04.13, Lei Tao

题目大意:给N个数,两两相减有m=C(N,2)种结果,找出(m/2)-th小的差。

思路:两次二分,第一次二分找那个差数。第二次算出左边有多少比他小的数能够使它们的差小于第一次二分时的数

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.*;

public class Main {
	static int n;
	static int a[] = new int[100000];
	static int m;
	static int solve(int x,int y,int val,int flag){
		while(x<=y){
			int mid=(x+y)/2;
			if(val-a[mid]<=flag)
				y=mid-1;
			else
				x=mid+1;

		}
		return y;
	}
	static boolean ok(int val){
		int j,k=0;
		for(int i=2;i<=n;i++){
			j=solve(1,i-1,a[i],val);
			k+=i-j-1;
		}
		if(k<m)
			return false;
		else
			return true;
	}
	public static void main(String[] args) throws IOException {
		//Scanner scan = new Scanner(System.in);
		StreamTokenizer st = new StreamTokenizer(new BufferedReader(
				new InputStreamReader(System.in)));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		while (st.nextToken()!=StreamTokenizer.TT_EOF) {
			n =(int)st.nval;
			if(n*(n-1)/2%2!=0){
				m=(n*(n-1)/2+1)/2;
			}
			else
				m=n*(n-1)/2/2;

			for (int i = 1; i <=n; i++) {
				st.nextToken();
				a[i] = (int)st.nval;
			}
			Arrays.sort(a,1,n+1);
			int l = 0, r = a[n]-a[1];
			while(l<=r){
				int mid=(l+r)/2;
				if(ok(mid))
					r=mid-1;
				else
					l=mid+1;
			}
			out.println(l);
			out.flush();
		}
	}

}

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-10-26 18:31:00

POJ 3579- Median的相关文章

POJ 3579 Median 二分+思维

POJ 3579 Median 二分+思维 题意 给你一些数,然后求这些数相互之间差的绝对值,然后绝对值排序,找到中间那个数. 解题思路 我反正一直开始是没有想到这个题竟然可以用二分来做.━━( ̄ー ̄*|||━━. 二分枚举答案,假设枚举值为mid,然后就是在排好序的序列中对每一个num[i]找到在i之后,有多少个大于num[i]+mid的数的个数(数列里的值比num[i]+mid大,说明该值与num[i]作差形成的新数列里的数比中位数mid大),用lower_bound计算所有差值比mid大于

poj 3579 Median 二分查找与lower_bound

题意: 给n个数,他们两两之间较大数减去较小数总共有n*(n-1)/2个数,要求这些数的中位数. 分析: 两次二分,第一次枚举答案,第二次判断该数是否可能成为中位数. 代码: //poj 3579 //sep9 #include <iostream> #include <algorithm> using namespace std; const int maxN=1e5+10; int a[maxN]; int n,m; int test(int x) { int sum=0; f

poj 3579 Median (二分搜索之查找第k大的值)

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

POJ 3579 Median(二分答案+Two pointers)

[题目链接] http://poj.org/problem?id=3579 [题目大意] 给出一个数列,求两两差值绝对值的中位数. [题解] 因为如果直接计算中位数的话,数量过于庞大,难以有效计算, 所以考虑二分答案,对于假定的数据,判断是否能成为中位数 此外还要使得答案尽可能小,因为最小的满足是中位数的答案,才会是原差值数列中出现过的数 对于判定是不是差值的中位数的过程,我们用尺取法实现. 对于差值类的题目,还应注意考虑边界,即数列只有一位数的情况. [代码] #include <cstdio

POJ - 3579 Median 二分

题目大意:给出n个数,要求将这n个数两两相减,把这些相减得到的数排序后,输出位置在中间的那个数 解题思路:如果两两相减再排序复杂度太高,肯定超时了,不妨换另一种思路 枚举最中间的那个数,然后判断一下相减得到的数有多少个大于等于枚举的数 如何判断上面所说的那句呢,其实不用把每个数相减,只需要排序一下,然后将当前这个数 + 枚举的那个数,然后在数组中找到大于等于这个数的第一个位置(lower_bound()),再用n减去那个数的位置就可以知道有多少个相减的结果会大于等于这个数了 最后只需要判断一下大

poj 1975 Median Weight Bead(传递闭包 Floyd)

链接:poj 1975 题意:n个珠子,给定它们之间的重量关系,按重量排序,求确定肯定不排在中间的珠子的个数 分析:因为n为奇数,中间为(n+1)/2,对于某个珠子,若有至少有(n+1)/2个珠子比它重或轻,则它肯定不排在中间 可以将能不能确定的权值初始化为0,能确定重量关系的权值设为1 #include<stdio.h> #include<string.h> int a[110][110]; int main() { int T,n,m,i,j,k,d,x,sum; scanf(

POJ 3579 3685(二分-查找第k大的值)

POJ 3579 题意 双重二分搜索:对列数X计算∣Xi – Xj∣组成新数列的中位数 思路 对X排序后,与X_i的差大于mid(也就是某个数大于X_i + mid)的那些数的个数如果小于N / 2的话,说明mid太大了.以此为条件进行第一重二分搜索,第二重二分搜索是对X的搜索,直接用lower_bound实现. #include <iostream> #include <algorithm> #include <cstdio> #include <cmath&g

【POJ - 3579 】Median(二分)

Median Descriptions 给N数字, X1, X2, ... , XN,我们计算每对数字之间的差值:∣Xi - Xj∣ (1 ≤ i < j ≤N). 我们能得到 C(N,2) 个差值,现在我们想得到这些差值之间的中位数. 如果一共有m个差值且m是偶数,那么我们规定中位数是第(m/2)小的差值. Input 输入包含多测每个测试点中,第一行有一个NThen N 表示数字的数量.接下来一行由N个数字:X1, X2, ... , XN( Xi ≤ 1,000,000,000  3 ≤

Divide and conquer:Median(POJ 3579)

    快速求两数距离的中值 题目大意:给你一个很大的数组,要你求两个数之间的距离的中值 二分法常规题,一个pos位就搞定的事情 1 #include <iostream> 2 #include <algorithm> 3 #include <functional> 4 5 using namespace std; 6 typedef long long LL_INT; 7 8 static int nums[100002]; 9 bool judge(LL_INT,

POJ 1975 Median Weight Bead

Median Weight Bead Time Limit: 1000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 197564-bit integer IO format: %lld      Java class name: Main There are N beads which of the same shape and size, but with different weights.