zoukankan      html  css  js  c++  java
  • Median

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

    Median
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11805   Accepted: 4164

    Description

    Given N numbers, X1X2, ... , 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 X1X2, ... , XN, ( X≤ 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小的数。

    思路:最容易想到的就是暴力了 但是复杂度n*n 绝对超时的,但是除了这个方法我真的没有想到有什么方法不会超时。
    其实自己想了一下二分,但是二分不应该答案是在一个区间之中的所有数都有可能吗? 但是这里只能是那些两两之间相减能得出来的数啊 所以也否定了二分。。。
    其实就是二分,只是自己对二分的理解还不够深刻罢了。 仔细想想,就算你用二分来求区间里的每一个数,到最后得出来的答案肯定也是两两相减能得到的 为什么呢? 因为只有这个数才是最符合条件的
    二分到最后也就是求出最符合条件的呀。。。
    有一些细节要注意,都在代码中了。
    看代码:
    #include<iostream>
    #include<string.h>
    #include<vector>
    #include<algorithm>
    #include<stdio.h>
    using namespace std;
    const int maxn=1e5+5;
    int N;
    int M;
    int temp;
    int a[maxn];
    bool judge(int x)
    {
        int sum=0;//有多少个比a[i]+x小的数
        for(int i=0;i<N;i++)
        {
            int cnt=lower_bound(a,a+N,a[i]+x)-a;//找到第一个大于等于a[i]+x的数的下标  也就是找到了有多少个数 减去a[i]小于x   剩余的数就是大于x的了
            sum+=N-cnt;
        }
        //cout<<sum<<endl;
        /**
        注意这里要分奇偶情况 不要问我为什么  我也是输出中间数据才明白的  讲不清
        **/
        if(temp%2==1)//奇数个
        {
            if(sum>=M) //代表x太小了
                return true;
            return false;//x太大了
        }
        else
        {
            if(sum>M) //代表x太小了
                return true;
            return false;//x太大了
        }
    
    }
    int main()
    {
        //while(cin>>N)
        while(scanf("%d",&N)!=EOF)
        {
            for(int i=0;i<N;i++) //cin>>a[i];
                scanf("%d",&a[i]);
            /**
            为什么可以排序呢?  因为求的是ai-aj的绝对值 如果是负数的话 也就相当于aj-ai
            **/
            sort(a,a+N);
            temp=N*(N-1)>>1;
            M=(temp+1)>>1;//答案是第几小的
            int l=0;
            int r=a[N-1]-a[0];
            int ans;
            while(l<=r)
            {
    
                int mid=(l+r)>>1;
                //cout<<mid<<endl;
                if(judge(mid))//太小了
                {
                    ans=mid;
                    l=mid+1;
                }
                else r=mid-1;
            }
            printf("%d
    ",ans);
            //cout<<ans<<endl;
        }
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    分配一维动态数组or 二维动态数组的方法以及学习 new 方法or vector
    关于i++与++i的学习讨论!
    vector 中需要注意的东西!
    c++中 函数的默认参数 学习
    为什么 c++中函数模板和类模板的 声明与定义需要放到一起?
    c++中赋值运算符重载为什么要用引用做返回值?
    为什么const对象只能调用const成员函数,而不能调用非const成员函数?
    java 文件读写
    java Vector
    getRequestDispatcher
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10390721.html
Copyright © 2011-2022 走看看