zoukankan      html  css  js  c++  java
  • HDU6231(二分+尺取)

    Alice are given an array A[1..N] with N numbers.
    
    Now Alice want to build an array B by a parameter K as following rules:
    
    Initially, the array B is empty. Consider each interval in array A. If the length of this interval is less than K, then ignore this interval. Otherwise, find the K-th largest number in this interval and add this number into array B.
    
    In fact Alice doesn't care each element in the array B. She only wants to know the M-th largest element in the array B. Please help her to find this number.
     
    
    Input
    The first line is the number of test cases.
    
    For each test case, the first line contains three positive numbers N(1≤N≤105),K(1≤K≤N),M. The second line contains N numbers Ai(1≤Ai≤109).
    
    It's guaranteed that M is not greater than the length of the array B.
     
    
    Output
    For each test case, output a single line containing the M-th largest element in the array B.
     
    
    Sample Input
    2
    5 3 2
    2 3 1 5 4
    3 3 1
    5 8 2
     
    
    Sample Output
    3
    2

    正确:

    反向思维:

           首先所求答案一定为A数组中的元素,通过二分寻找元素X ;

           然后通过  尺取法以O(n)的时间复杂度 找到   所有A的连续子区间    中   第K大元素>=X的区间  

               因为l,r遍历,如果[l,r]中第K大元素>=X, 后续加入的元素没有影响  ans(所求区间数 )+= n-r

          所以X在所有第K大元素组成的区间中至少为ans大(因为[l,r]后序加入的元素中可能有比X大的元素,也有等于X的元素)

          通过叫ans与m的大小,最后求得答案 

    注意:X不一定在所有第K大组成的元素中;(PS:因为这个错误卡了一天)

    #include<iostream>
    #include<algorithm>
    #define max 100005
    typedef long long ll;
    using namespace std;
    int n,k,a[max],b[max];
    ll m;
    ll judge(int x) {
        int num=0;
        ll ans = 0;
        int l,r;l=r=0;
        while(l<n) {
            while(r<n&&num<k) {
                if(a[r++]>=x) {
                    num++;
                }
            }
            if(num>=k) ans += n-r+1;
            if(a[l++]>=x) num--;
            
        }
        return ans;
    }
    int main() {
        int t;
        cin>>t;
        while(t--) {
            
            cin>>n>>k>>m;
            for(int i=0; i<n; i++) {
                cin>>a[i]; b[i] = a[i];
            }
            sort(b,b+n);
            int l,r,mid; l=0, r=n-1; ll ans = 0;
            while(l<=r) {
                mid = (l+r)>>1;
                if(judge(b[mid])>=m) {
                    ans = b[mid];
                    l = mid+1;
                }else{
                    r = mid-1;
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    错误原因:

          通过X比较出答案,并非X为答案

          这里是逐步寻找最优解的过程,而不是精确查找

    #include<iostream>
    #include<algorithm>
    #define max 100005
    typedef long long ll;
    using namespace std;
    int n,k,a[max],b[max];
    ll m;
    ll judge(int x) {
        int num=0;
        ll ans = 0;
        int l,r;l=r=0;
        while(l<n) {
            while(r<n&&num<k) {
                if(a[r++]>=x) {
                    num++;
                }
            }
            if(num>=k) ans += n-r+1;
            if(a[l++]>=x) num--;
            
        }
        return ans;
    }
    int main() {
        int t;
        cin>>t;
        while(t--) {
            
            cin>>n>>k>>m;
            for(int i=0; i<n; i++) {
                cin>>a[i]; b[i] = a[i];
            }
            sort(b,b+n);
            int l,r,mid; l=0, r=n-1; ll ans = 0;
            while(l<=r) {
                mid = (l+r)>>1;
    //            cout<<"left="<<l<<" right="<<r<<endl;
    //            cout<<"b[mid]="<<b[mid]<<endl;
                if(judge(b[mid])==m){break;} 
                if(judge(b[mid])>m) {
                    l = mid+1;
                }else{
                    r = mid-1;
                }
            }
            cout<<b[mid]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    JS生成Guid
    MVC——分页
    MVC入门——删除页
    MVC入门——编辑页
    MVC入门——详细页
    MVC入门——列表页
    MVC入门——增
    pandas使用
    简单线性回归预测实现
    flask 自定义url转换器
  • 原文地址:https://www.cnblogs.com/Lemon1234/p/11603554.html
Copyright © 2011-2022 走看看