双指针的做法
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n,s;
int S[N];
int a[N];
int lens = N;
int main()
{
cin >> n >> s;
for(int i=0;i < n;i++)
{
cin >> a[i];
S[i] = S[i-1] + a[i];
}
for(int i=0,j=0;i < n;i++) // i在前面,j在后面
{
while(S[j] - S[i-1] < s && j < n) j++;
// cout << S[j] - S[i-1] << " "<< j << " " << i << endl;
lens = min(lens,j - i + 1);
}
if(lens == N) cout << 0;
else cout << lens;
return 0;
}
前缀和+二分查找
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX_N = 1000010;
int n, m;
int nums[MAX_N];
int preSum[MAX_N];
int binartSearch(int sum[],int l, int r)
{
int start = l;// 第一个位置固定。 不是要找中间值,而是以第一个位置为准的值
while (l < r) {
int mid = (l + r) >> 1;
if (sum[mid] - sum[start] >= m) {
r = mid;
}
else {
l = mid + 1;
}
}
return (l-start);
}
int solve()
{
int ret = MAX_N;
for (int i = 1; i <= n; i++) {
preSum[i] = preSum[i - 1] + nums[i];
}
//全部加起来都无法达到标准
if (preSum[n] < m) return 0;
for (int i = 1; i < n; i++) {
//if(preSum[i]+m <= preSum[n]){
if (preSum[n] - preSum[i] >= m) { // 只要有可能就去二分
int idx = binartSearch(preSum,i,n);
ret = min(ret, idx);
}
}
if (ret == MAX_N) ret = 0;
return ret;
}
int main()
{
int loop;
cin >> loop;
while (loop--) {
cin >> n >> m;
memset(nums,0,sizeof(nums));
memset(preSum, 0, sizeof(preSum));
for (int i = 1; i <= n; i++) {
cin >> nums[i];
}
cout << solve() << endl;
}
return 0;
}