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;
    }
  • 相关阅读:
    quota磁盘配额
    lvm管理
    快照
    分区工具
    课下测试03!03!03!题目截图及解析(不完全正确)第四周--信息安全系统设计基础
    2017-2018-1 20155307《信息安全技术李冬冬》实验二——Windows口令破解
    2017-2018-1 20155301 20155307 20155339 《信息安全系统设计基础》 实验一 开发环境的熟悉
    2017-2018-1 20155307 《信息安全系统设计基础》第5周学习总结
    PGP的原理与使用
    2017-2018-1 20155307 《信息安全系统设计基础》第四周学习总结
  • 原文地址:https://www.cnblogs.com/Lemon1234/p/11603554.html
Copyright © 2011-2022 走看看