https://vjudge.net/problem/POJ-3061
给你t,t组数据
然后给你一个 长度为m的串,问你字串中,连续长度大于等于n的最小长度为多少。
开始用的暴力查找。妥妥tle。
并且我还窃以为这就是尺取法qwq。。
看到真正的才知道错了。
还有一种方法 是用二分,感觉也挺好
https://vjudge.net/problem/POJ-3061
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn=100006;
int main()
{ int t;
int sum[maxn];
int a[maxn];
int m,n;
cin>>t;
while(t--)
{ scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{scanf("%d",&a[i]);
//sum[i]=sum[i-1]+a[i];
}
int ans=m+1;
int t=1,s=1;
int all=0;
for(;;)
{while(t<=m&&all<n)
all+=a[t++];
if(all<n) break;
ans=min(ans,t-s);
all-=a[s];
s++;
}
if(ans==m+1)
cout<<"0"<<endl;
else
cout<<ans<<endl;
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100007;
int main()
{ int t;
int sum[maxn];
int a[maxn];
int m,n;
scanf("%d",&t);
while(t--)
{ scanf("%d%d",&m,&n);
sum[0]=0;
for(int i=1;i<=m;i++)
{ scanf("%d",&a[i]);
sum[i]=a[i]+sum[i-1];
}
if(sum[m]<n){
printf("0\n");
continue;
}
int ans=m;
for(int i=1;sum[i]+n<=sum[m];i++)
{ int t=lower_bound(sum+i,sum+m,sum[i]+n)-sum;
ans=min(ans,t-i);
}
cout<<ans<<endl;
}
return 0;
}
```、
自己补的尺取法写法。
我觉得我这个写的比较好理解。
<div class="se-preview-section-delimiter"></div>
include
include
using namespace std;
/* 尺取法。
*/
typedef long long ll;
const int maxn=1e5+6;
ll a[maxn];
ll sum;
int main()
{ int t,m;ll n;
scanf(“%d”,&t);
while(t–){
scanf(“%d%lld”,&m,&n);
for(int i=1;i<=m;i++){
scanf(“%lld”,&a[i]);
}
sum=0;
int r=1;
int l=1;
int ans=1e9+7;
for(int i=1;i<=m;i++,r++){
sum+=a[i];
while(sum>=n){
ans=min(ans,r-l+1);
sum-=a[l];
l++;
}
}
if(ans==1e9+7)
puts(“0”);
else
printf(“%d\n”,ans);
}
return 0;
}
“`