先看看基本定义:
尺取法是一种线性算法,也是一种高效的枚举区间的方法。
记 ( L , R ) 两个端点为一个序列内以l为起点的最短合法区间,如果r随l的增大而增大的话,我们就可以使用尺取法。
具体的做法是:
1.初始化左右端点
2.不断扩大右端点,直到满足条件
3.如果第二步中无法满足条件,则终止,否则更新结果
4.将左端点扩大1,然后回到第二步
因为 R 随 L 增大而增大,所以 R 只有 n次变化的机会,所以时间复杂度为O(n)。
然后看看题目逝一下:
楠楠在网上刷题,感觉第一题:求两数的和(A+B Problem)太无聊了,于是增加了一题:求和为C的Problem,难倒了一群小朋友,哈哈。 题目是这样的:给出N个正整数,一个值C,要求在这N个整数中找一段连续的数(至少2个数),使得它们的和等于C,问这样的方案有多少种? 例如:N=8,C=7,8个整数是:2 5 1 1 2 4 7 1。答案是3。具体方案:(2, 5)、(5,1,1)、(1,2,4)。
输入格式
第一行2个正整数:N,C。
第二行:N个正整数。
数据范围:N的范围是[1…100,000]。C的范围是[1…1,000,000,000]。N个整数中每个数的范围是:[1…1,000,000,000]。
输出格式
一个整数,表示该串数中包含的所有方案数。
输入/输出例子1
输入:
4 5 1 4 1 4
输出:
3
样例解释
无
直接上代码叭:
#include<bits/stdc++.h>
using namespace std;
int n,c,a[100005],k,ans;
int main(){
cin>>n>>c;
for (int i=1;i<=n;i++)
cin>>a[i];
k=k+a[1];
for (int x=1,y=2;y<=n;y++)
{
k+=a[y];
while(k>c)
k-=a[x++];
if (k==c && y-x>0) ans++;
}
cout<<ans;
return 0;
}