2020.1.17每日一题“尺取”

@LBG1587265692

尺取是什么意思

尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。

为什么要用尺取

之所以需要掌握这个技巧,是因为尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的时候,所以尺取法是一种高效的枚举区间的方法,一般用于求取有一定限制的区间个数或最短的区间等等。

怎么实现尺取

尺取法通常适用于选取区间有一定规律,或者说所选取的区间有一定的变化趋势的情况,通俗地说,在对所选取区间进行判断之后,我们可以明确如何进一步有方向地推进区间端点以求解满足条件的区间,如果已经判断了目前所选取的区间,但却无法确定所要求解的区间如何进一步得到根据其端点得到,那么尺取法便是不可行的。首先,明确题目所需要求解的量之后,区间左右端点一般从最整个数组的起点开始,之后判断区间是否符合条件在根据实际情况变化区间的端点求解答案。

总结一下过程大致分为四步:

1.初始化左右端点,即先找到一个满足条件的序列。

2.在满足条件的基础上不断扩大右端点。

3.如果第二步无法满足条件则终止,否则更新结果。

4.扩大左端点,并且回到第二步。

真题演练

我去网上搜了下尺取的相关题目拿了道出现频率较高的来举例子

**给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度
输入
n = 10,m = 15
5 1 3 5 10 7 4 9 2 8
输出
2
**
尺取过程如下:在这里插入图片描述
代码实现:

#include<stdio.h>
int main()
{
    int t,n,m,ans,minx,sum,i,j,w;
    int a[10010];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        j=0;w=0;sum=0;ans=n+1;
        while(1)
        {
            while(j<n&&sum<m)
                sum=sum+a[j++];//先找到一个满足条件的序列,在满足条件的基础上不断扩大右端点
            if(sum<m)
                break;
            minx=j-w;
            ans=min(ans,minx);
            sum=sum-a[w];//扩大左端点
            w++;
        }
            printf("%d\n",ans)}
    return 0;
}

发布了32 篇原创文章 · 获赞 5 · 访问量 914

猜你喜欢

转载自blog.csdn.net/LebronGod/article/details/104025600