本题采用尺取法,
以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; }