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

【题目链接】 http://poj.org/problem?id=3579

【题目大意】

  给出一个数列,求两两差值绝对值的中位数。

【题解】

  因为如果直接计算中位数的话,数量过于庞大,难以有效计算,
  所以考虑二分答案,对于假定的数据,判断是否能成为中位数  
  此外还要使得答案尽可能小,因为最小的满足是中位数的答案,才会是原差值数列中出现过的数
  对于判定是不是差值的中位数的过程,我们用尺取法实现。
  对于差值类的题目,还应注意考虑边界,即数列只有一位数的情况。

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
int n,a[100010];
int main(){
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        int l=0,r=a[n],m=n*(n-1)/4+((n*(n-1)/2)&1),ans=0;
        if(n==1){puts("0");continue;}
        int Ans=0;
        while(l<=r){
            int mid=(l+r)>>1,pre=1,ans=0;
            for(int i=2;i<=n;i++){
                while(a[i]-a[pre]>mid)pre++;
                ans+=i-pre;
            }if(ans>=m)r=mid-1,Ans=mid;
            else l=mid+1;
        }printf("%d\n",Ans);
    }return 0;
}
时间: 2024-08-05 11:17:55

POJ 3579 Median(二分答案+Two pointers)的相关文章

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 二分

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

POJ 3122 Pie 二分答案

Pie Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9653   Accepted: 3478   Special Judge Description My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of v

POJ 3104 Drying(二分答案)

题目链接:http://poj.org/problem?id=3104 Drying Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11128   Accepted: 2865 Description It is very hard to wash and especially to dry clothes in winter. But Jane is a very smart girl. She is not afra

POJ3579 Median(二分答案 + O(N)判定)

传送门 大意:给出N个数,对于存有每两个数的差值的序列求中位数,如果这个序列有偶数个元素,就取中间偏小的作为中位数. 因为N<=100000,所以想要求出每一个差值是不可行的,我们很容易想到二分答案. 在二分答案时我们会进行判定,求出小于等于枚举值的个数,我看其他人的判定似乎都是O(NlogN) 的,我在这里就给出一个O(N)的判定方法. 首先同样将数组排序(我们命名为a数组好了) 我们枚举一个区间[l,r),因为当r增加的时候,要使[l,r)中的数都大于于等于a[r]?枚举值,l必定不会增加,

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 3080 Blue Jeans(后缀数组+二分答案)

[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通过拼接符拼成一个串,做一遍后缀数组,二分答案,对于二分所得值,将h数组大于这个值的相邻元素分为一组,判断组内元素是否覆盖全字典,是则答案成立,对于答案扫描sa,输出第一个扫描到的子串即可. [代码] #include <cstdio> #include <cstring> #inclu

字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在学习后缀数组的时候已经做过一遍了,但是现在主攻字符串hash,再用字符串hash写一遍. 这题的思路是这样的: 1)取较短的串的长度作为high,然后二分答案(每次判断长度为mid=(low+high)>>1是否存在,如果存在就增加下界:不存在就缩小上界): 2)主要是对答案的判断(judge函数