HDU-6231(二分+双指针)

Posted aaddvvaanntteezz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-6231(二分+双指针)相关的知识,希望对你有一定的参考价值。

Problem Description
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(1N105),K(1KN),M. The second line contains N numbers Ai(1Ai109).

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
题意:给你一个长度为n的数组,求数组的所有子区间的第k大(没有第k大就忽略这个区间)的数中的第m大是多少?
题解:二分答案,用双指针找出所有区间大于等于x的个数再与m比较
AC代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int n,k;
long long m;
int a[100005];
int b[100005];
long long judge(int x)

    int ll=1,num=0;
    long long ans=0;
    for(int i = 1;i <= n;++i)
    
        if(a[i]>=x)
            num++;
        if(num==k)
        
            ans+=n-i+1;
            while(a[ll]<x)//双指针移动
            
                ans+=n-i+1;
                ll++;
            
            num--;
            ll++;
        
    
    return ans;

int main()

    int t;
    scanf("%d",&t);
    while(t--)
    
        scanf("%d%d%lld",&n,&k,&m);//m会超过int
        for(int i = 1;i <= n;++i)
            scanf("%d",&a[i]);
            b[i]=a[i];
        
        sort(b+1,b+1+n);
        int num=unique(b+1,b+1+n)-b-1;
        int l=1,r=num;
        while(l<=r)
        
            int mid=l+r>>1;
            long long temp=judge(b[mid]);
            if(temp<m)
                r=mid-1;
            else if(temp>=m)
                l=mid+1;
        
        printf("%d\n",b[r]);
    
    return 0;

 

 

以上是关于HDU-6231(二分+双指针)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6231 (二分+双指针)

[E双指针] lcLCP28. 采购方案(双指针+二分)

[M双指针] lc611. 有效三角形的个数(二分+双指针+线性扫描+算法优化)

[双指针] aw3624. 三值字符串(双指针+好题)

有效三角形的个数--二分和双指针

leetcode.1574 删除最短的子数组使剩余数组有序 - 阿里笔试 双指针 二分