POJ 3061 Subsequence 二分查找
题目大意:给出长度为n的一个序列,给出一个数字S,求长度最短的序列和大于等于S的连续子序列,输出该长度,如果没有答案输出0。
题目思路:看数据范围,这道题就是卡时间的。我们可以用sum[i]记录前i项和,然后用二分优化查找过程。这样时间复杂度为 n*logn。具体看代码吧。
#include<cstdio> #include<stdio.h> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 1000005 #define mod 1000000007 using namespace std; int a[MAX],sum[MAX]; int main() { int T,i,j,n,minn,s,ok,flag; scanf("%d",&T); while(T--) { sum[0]=0; flag=0; scanf("%d%d",&n,&s); for(i=1;i<=n;i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i];//记录前i项和 } minn=INF; for(i=1;i<=n;i++) { int L=0; int R=i; ok=0; if(a[i] >= s)//若发现有元素大于S直接跳出 { flag=1; minn=1; break; } while(R > L) { int mid=L+(R-L)/2; if(sum[i]-sum[mid] >= s) { ok=1; L=mid+1; minn=min(minn,(i-mid)); } else { R=mid; } } if(ok) flag=1;//若存在答案标记一下 } if(!flag) minn=0; printf("%d\n",minn); } return 0; }