51nod 1105 二分套二分

来源:互联网 发布:网络棋牌作弊器 编辑:程序博客网 时间:2024/05/21 11:00




题意:

中文题

题解:

思路:二分套二分

步骤:

1···对两个数组进行排序

2···找到二分答案所需的上下界进行二分(mid)

3···然后枚举一个数组下标,对另外一个数组下标进行二分

4···第三步用函数计算比mid大的数有多少个

这样二分下来即可以得到所需要第K大的数


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,k;#define LL long long#define MAXN 50005LL a[MAXN],b[MAXN];int cmp(const void *x,const void *y){    return *(LL *)y - *(LL *)x;}LL deal(LL num){    LL cnt=0;    for(int i=0;i<n;i++){        LL left=0,right=n-1;        LL t=0;        while(left<=right)        {            LL mid=(left+right)>>1;            if(a[i]*b[mid]>=num)                t=mid+1,left=mid+1;            else                right=mid-1;        }        cnt+=t;    }    return cnt;}int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&k)!=EOF)    {        for(int i=0;i<n;i++)            scanf("%lld%lld",&a[i],&b[i]);        qsort(a,n,sizeof(a[0]),cmp);        qsort(b,n,sizeof(b[0]),cmp);        LL ans=0;        LL right=a[0]*b[0];        LL left=a[n-1]*b[n-1];        while(left<=right)        {            LL mid=(left+right)>>1;            if(deal(mid)>=k)                ans=mid,left=mid+1;            else                right=mid-1;        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击