导航

UESTC 1087 【二分查找】

Posted on 2015-10-07 16:37  tun~  阅读(163)  评论(0编辑  收藏  举报

问了某明==shit

中文题意不解释。

因为数据的范围是1e9以内的所以我们可以通过二分的方法枚举可能的中位数。

用二分法每次判断某一数字比中位数大还是比中位数小。

判断方法是,枚举以第n个数为起点的差值,累计差值大于该该数字的数量。这里用到lower_bound进行统计==(这里也是二分)

具体解释看代码..

这里学到了一种新的二分的写法...

反思:

这题好像不难,但是就是没有思路很不爽,很多东西其实都学过了但是都不会应用,题还要多做多思考。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
long long tmp[100005];
long long n;
int main()
{
    while(scanf("%lld",&n)!=EOF)
    {
        for(long long i=0;i<n;i++)
        {
            scanf("%lld",&tmp[i]);
        }
        long long l=0,r=0x3f3f3f3f3f3f3f;//这里的初值并不是1e9
        long long toend=(n-1)*n/2;
        sort(tmp,tmp+n);
        while(l+1<r)
        {
            long long mid=l+(r-l)/2;//找mid的方法
            //printf("%lld\n",r);
            long long ans=0;
            for(int i=0;i<n;i++)
            {
                ans+=tmp+n-lower_bound(tmp+i+1,tmp+n,tmp[i]+mid);//ans这里累计的是比二分枚举出的数字大于或者等于的数字的个数
            }
            if(ans<=toend/2)//一开始看别人的代码这里看不懂,后来自己写了写公式发现自己写的跟这个是一样的...这个只是变形而已
            {//如果ans小则说明枚举出的数字一定比正确的中位数要大了,所以要减小r
                r=mid;
            }
            else
            {
                l=mid;
            }
        }
        printf("%lld\n",l);
    }
}