题意:
n 个数,求出最小的相邻的数之和不小于s。
思路:
这里使用尺取法,也就是直接找到一段数,其值和必然大于s,这里应该体会sum的妙用。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int sum[100005];
int a[100005];
int n,s;
int main()
{
//freopen("in.txt","r",stdin);
int ncase;
scanf("%d",&ncase);
while(ncase--) {
scanf("%d%d",&n,&s);
memset(sum,0,sizeof(sum));
for(int i = 0;i < n; i++) {
cin>>a[i];
sum[i+1] = sum[i] + a[i];
}
if(sum[n] < s) {
cout<<"0"<<endl;
continue;
}
int ans = n;
for(int i = 0;sum[i] + s <= sum[n]; i++) {
int t = lower_bound(sum + i,sum + n,sum[i] + s) - sum;
ans = min(ans,t-i);
}
cout<<ans<<endl;
}
return 0;
}
更优解:
有点像是遍历!
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
int a[100005];
int sum;
int main()
{
//freopen("in.txt","r",stdin);
int ncase;
scanf("%d",&ncase);
while(ncase--) {
scanf("%d%d",&n,&m);
for(int i = 0;i < n; i++)
scanf("%d",&a[i]);
int s = 0,t = 0,ans = n + 1;
sum = 0;
while(true) {
while(t < n && sum < m) {
sum += a[t++];
}
if(sum < m)
break;
ans = min(ans,t - s);
sum -= a[s++];
}
if(ans > n)
ans = 0;
cout<<ans<<endl;
}
return 0;
}