尺取(板子)
描述 给出了N个正整数(10 <N <100 000)的序列,每个正整数均小于或等于10000,并给出了一个正整数S(S <100 000 000)。编写程序以查找该序列的连续元素的子序列的最小长度,其总和大于或等于S。
输入项 第一行是测试用例的数量。对于每个测试用例,程序必须从第一行读取数字N和S,并以一个间隔将其隔开。序列号在测试用例的第二行中给出,以间隔分隔。输入将以文件结尾结束。
输出量 对于每种情况,程序都必须将结果打印在输出文件的单独一行上。如果没有答案,则打印0。
样本输入 2 10 15 5 1 3 5 10 7 4 9 2 8 5 11 1 2 3 4 5 样本输出 2 3 |
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxn=1e5+100; int a[maxn]; int n,m; int main(){ int t; cin>>t; while(t--){ memset(a,0,sizeof(a)); cin>>n>>m; for(int i=1;i<=n;i++){ cin>>a[i]; } int l=1,r=1; int sum=0; int ans=1e9; while(1){ while(r<=n&&sum<m){//先找到一个合适的区间 sum+=a[r]; r++; } if(sum<m){//先判断再更新结果 break; } ans = min(ans,r-l); //如果数组中都加完了之后还是小于sum,就不用再循环了 sum-=a[l]; l++; } if(ans>n){ ans=0; } cout<<ans<<endl; } }
模板二:
这个模板二就是对于每一个i,向后找一个满足题意的j
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1e6+100; ll a[maxn]; int main(){ int t; cin>>t; while(t--){ int n,m; cin>>n>>m; ll s=0; for(int i=1;i<=n;i++){ cin>>a[i]; s+=a[i]; } if(s<m){ cout<<0<<endl; continue; } int ans=1e9; int j=1; ll sum=0; for(int i=1;i<=n;i++){ sum+=a[i]; while(sum-a[j]>=m){ sum-=a[j]; j++; } if(sum>=m){//3 4 5 ans=min(ans,i-j+1); } } cout<<ans<<endl; } }