标签:
题目链接:http://poj.org/problem?id=3061
题意:给定长度为n的数列整数,以及整数S,求出总和不少于S的连续子序列的长度的最小值。如果解不存在,则输出0。
尺取法:通常是指对数组保存一对下标(起点,终点),然后根据实际情况交替推进两个端点直到解决问题的方法,这个操作很像尺蠼虫故得名。
思路:所以可以先初始化起点s,终点g,再一步一步推进,直到sum>S,然后记录此时的序列长度,再推进s,sum-=num[s],再记录长度,直到sum<S,再推进g,这样的方法,s和g最多各推进n次,所以复杂度是O(n)。
//556K 79MS 尺取法 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; int a[100100]; int main() { int cas,n,aim; scanf("%d",&cas); while(cas--){ scanf("%d%d",&n,&aim); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int s=0,g=0; int sum=0,ans=(1<<30); for(;;){ while(sum<aim){ g++; if(g>n) break; sum+=a[g]; } if(sum<aim) break; ans=min(ans,g-s); sum-=a[++s]; } if(ans>n) printf("0\n"); else printf("%d\n",ans); } return 0; }
//948K 79MS 二分 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; int a[100100],sum[100100]; int main() { int cas; scanf("%d",&cas); while(cas--){ int n,s,ans=(1<<30); scanf("%d%d",&n,&s); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=n;i++){ sum[i]=sum[i-1]+a[i]; } if(sum[n]<s) { printf("0\n"); continue; } for(int i=0;sum[i]+s<=sum[n];i++){ int t=lower_bound(sum+i,sum+n+1,sum[i]+s)-(sum+i); ans=min(ans,t); } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/kalilili/article/details/43745031