尺取法。
不断更新指向可以执行数组区间的前后两个指针从零开始。
尺取法的模板代码为:
#include<iostream>
using namespace std;
int main()
{
while (1)
{
while ((判断的条件) && 当前区间应该不满足的值)
{
不断执行使得当前区间满足;
}
if (执行所有区间都不满足)break;
res = min(res, t - s)//或者是其他更新的条件
更新末尾指针;
更新当前区间
}
}
本题实现代码如下:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const long long INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int, int> pir;
int n, s;
int a[100005];
//int vis[100005];
void solve()
{
int res = 1<<25;//求最小值设置一个不会影响答案的最大最小数字
int s1 = 0, t = 0;
int sum = 0;
while (1)
{
while (t < n&&sum < s)
sum += a[t++];
if (sum < s) break;
//cout << res<<endl;
//cout <<"t"<< t << endl;
res = min(res, t-s1);
sum -= a[s1++];
}
// cout << res;
if (res == (1 << 25)) cout << 0 << endl;
else cout << res << endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
cin >> n >> s;
up(i, 0, n)
{
scanf("%d", &a[i]);//用scanf比较保险cin输入大数据太慢了
}
solve();
}
return 0;
}