本题采用尺取法,
以10 15 | 1 3 5 10 7 4 9 2 8为例子
定义了一个sum变量去求数组的一段序列的和,定义了 st 和 en 去指向数组的开头和结尾,判断他是否 > s
如果说当我们找到一个sum >= s的时候,这个时候就不用继续往下找了,反过来去拿sum减去st指向的第一个值 sum = sum - arr【st++】
如果说sum还是 > s,那么继续减,直到sum < s的时候,我们就可以把en往后移加入sum 即 sum = sum + arr【en++】
如果sum > s,sum = sum - arr【st++】,就这样循环往复直到en走到数组的尾部退出循环,然后再输出min(len,en - st)这个长度
代码如下
#include <iostream>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
int arr[MAXN];
int main(int argc, char** argv) {
ll t,n,s;
cin >> t;
while ( t-- ){
cin >> n >> s;
ll len = INT_MAX; //在这里定义也为了每轮执行len能保证不存脏数据
ll st = 1,en = 1,sum = 0; //同上
for ( int i = 1 ; i <= n ; i++ )
cin >> arr[i];
while ( 1 ){
while ( en <= n && sum < s ) sum += arr[en++];
if ( sum < s ) break; //找到终点还是没有大于s的数就停止查找输出,①在找到终点前就有了答案,②找到终点都没有找到答案
len = min( len , en - st );
sum -= arr[st++];
}
if ( len == INT_MAX ) len = 0; //如果没有找到答案,答案为0
cout << len << endl;
}
return 0;
}
京公网安备 11010502036488号