HDU5806 NanoApe Loves Sequence Ⅱ BestCoder Round #86 two-pointer

来源:互联网 发布:电子驱蚊器软件 编辑:程序博客网 时间:2024/06/05 23:06

NanoApe Loves Sequence Ⅱ

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)
Total Submission(s): 1123    Accepted Submission(s): 498


Problem Description
NanoApe, the Retired Dog, has returned back to prepare for for the National Higher Education Entrance Examination!

In math class, NanoApe picked up sequences once again. He wrote down a sequence with n numbers and a number m on the paper.

Now he wants to know the number of continous subsequences of the sequence in such a manner that the k-th largest number in the subsequence is no less than m.

Note : The length of the subsequence must be no less than k.
 

Input
The first line of the input contains an integer T, denoting the number of test cases.

In each test case, the first line of the input contains three integers n,m,k.

The second line of the input contains n integers A1,A2,...,An, denoting the elements of the sequence.

1T10, 2n200000, 1kn/2, 1m,Ai109
 

Output
For each test case, print a line with one integer, denoting the answer.
 

Sample Input
17 4 24 2 7 7 6 5 1
 

Sample Output
18
 

Source
BestCoder Round #86
 

Recommend
wange2014


题意:给你n个数,要求找出里面有多少个连续子串,其中第k个大的数不小于m

一直题意理解错误。。。第k个大的数的意思是数字从大到小排列第k个

解题报告:

其中提到的two-pointer,似乎就是两个指针,对一个区间进行操作

下面代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>using namespace std;const int maxn=200005;long long save[maxn];int main(){    int t;    scanf("%d",&t);    long long i,k,n,m;    while(t--){        scanf("%lld%lld%lld",&n,&m,&k);        for(i=1;i<=n;i++){            scanf("%lld",&save[i]);            if(save[i]>=m){                save[i]=1;            }else{                save[i]=0;            }        }        long long result=0;        long long ans=0;        long long p=0;        for(i=1;i+k-1<=n;i++){            while(ans<k&&p<=n){                p++;                if(save[p]){                    ans++;                }            }            if(ans>=k) result+=n-p+1;            if(save[i]) ans--;        }        printf("%lld\n",result);    }    return 0;}


首先先将输入的数字进行01处理,然后用i,p来指向save的区间,在这个区间内,如果和>=18的话,那么区间末尾位置到母串末位位置都符合题意。

接着左指针向右移一位,如果为移动前的左指针的数是1,那么后面会重复统计所以将ans--,如果是0将和后面的数字一起构成新的子串,就不操作


0 0
原创粉丝点击