zoukankan      html  css  js  c++  java
  • zoj 3278 8G Island(二分)

    题意:给出n个元素的数组a和m个元素的数组b,求数组a中元素与数组b中元素相乘所得乘积的第k大值;

    思路:暴力超时,采用二分;先将两数组从大到小排序,外层二分枚举答案,内层二分查找与当前枚举值相等的乘积所在的区间;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    #define inf 100000000010
    using namespace std;
    ll kth,n,m;
    ll a[500010],b[500010];
    int cmp(int a1,int b1)
    {
        return a1>b1;
    }
    int main()
    {
        int k,i,j;
        while(scanf("%lld%lld%lld",&n,&m,&kth)!=EOF)
        {
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            for(i=1;i<=n;i++) scanf("%lld",&a[i]);
            for(i=1;i<=m;i++) scanf("%lld",&b[i]);
            sort(a+1,a+n+1,cmp);
            sort(b+1,b+m+1,cmp);
            b[0]=inf;b[m+1]=-1;
            ll Min=a[n]*b[m];
            ll Max=a[1]*b[1];
            ll Low=Min;
            ll High=Max;
            ll ans=Max;
            while(Low<=High)
            {
                ll Mid=(Low+High)/2;
                ll key=Mid;
                ll s1=0,s2=0;
                for(i=1;i<=n;i++)
                {
                    int low,high,res;
                    ll val=a[i]*b[1];
                    ll val2=a[i]*b[m];
                    if(val2>key)
                    {
                        s1+=m;
                        continue;
                    }
                    if(val<key)
                    {
                        s2+=m;
                        continue;
                    }
                    low=1,high=m,res=0;
                    while(low<=high)
                    {
                        int mid=(low+high)/2;
                        val=a[i]*b[mid];
                        val2=a[i]*b[mid+1];
                        if(val>key&&val2<=key)
                        {
                            res=mid;
                            break;
                        }
                        else if(val2>key)
                            low=mid+1;
                        else
                            high=mid-1;
                    }
                    s1+=res;
                    low=1,high=m,res=m+1;
                    while(low<=high)
                    {
                        int mid=(low+high)/2;
                        val=a[i]*b[mid];
                        val2=a[i]*b[mid-1];
                        if(val<key&&val2>=key)
                        {
                            res=mid;break;
                        }
                        else if(val2<key)
                        {
                            high=mid-1;
                        }
                        else
                            low=mid+1;
                    }
                    s2+=(m-res+1);
                }
                ll left=s1+1;
                ll right=n*m-s2;
                if(left<=kth&&kth<=right)
                {
                    ans=key;break;
                }
                else if(kth<left)
                {
                    Low=Mid+1;
                }
                else High=Mid-1;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 264. Ugly Number II
    LeetCode 231. Power of Two
    LeetCode 263. Ugly Number
    LeetCode 136. Single Number
    LeetCode 69. Sqrt(x)
    LeetCode 66. Plus One
    LeetCode 70. Climbing Stairs
    LeetCode 628. Maximum Product of Three Numbers
    Leetcode 13. Roman to Integer
    大二暑假周进度报告03
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4574906.html
Copyright © 2011-2022 走看看