Question Link: Http://poj.org/problem? Id = 3061
Theme: Find the shortest sequence length so that the sequence element and length are greater than S.
Solutions:
Two ideas.
One is binary + prefix and. Complexity O (nlogn ). A little slow.
Length of the binary enumeration sequence. If feasible, small to the left; otherwise, large to the right.
After prefix and preprocessing, sum the values in O (1.
#include "cstdio"#include "cstring"int sum[100005],n,s,a,T;bool check(int x){ int l,r; for(int i=1;i+x-1<=n;i++) { l=i,r=i+x-1; if(sum[r]-sum[l-1]>=s) return true; } return false;}int main(){ //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&s); for(int i=1;i<=n;i++) { scanf("%d",&a); sum[i]=sum[i-1]+a; } int l=0,r=n,ans=0; while(l<=r) { int mid=l+(r-l)/2; if(check(mid)) {ans=mid;r=mid-1;} else l=mid+1; } printf("%d\n",ans); memset(sum,0,sizeof(sum)); }}
Bipartite
The other is the ruler acquisition introduced by a famous Japanese ACM book. Complexity O (N)
This method is simple.
1. For L = 1, first find the first length that meets the requirements (of course not necessarily the optimal result ). During this period, r ++ keeps stretching.
(2) Yes. Now I have to kill the first element and make L ++. Starting from the second element, do not meet the requirements to continue stretching R. Update ans. Continue to play the second element.
③ Kick and kick until the r cannot be stretched and does not meet the requirements, break.
There is only one question in this method, that is, if R is not moved back, is the result correct?
Consider that l is always moving to the right, and R is not necessary to move to the left. R is directed only when the conditions are not met, otherwise it is parked in the original position.
At this time, we can find all feasible intervals by moving L. It can be associated with the sliding rheostat, fixed R, and slide L.
#include "cstdio"#include "cstring"#include "iostream"using namespace std;int a[100005],n,s,l,r,T,sum,ans;int main(){ //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&s); for(int i=1;i<=n;i++) scanf("%d",&a[i]); l=1,r=1,sum=0,ans=0x3f3f3f3f; while(true) { while(sum<s&&r<=n) sum+=a[r++]; if(sum<s) break; ans=min(ans,r-l); sum-=a[l++]; } if(ans==0x3f3f3f3f) printf("0\n"); else printf("%d\n",ans); }}
13592296 |
Neopenx |
3061 |
Accepted |
548 K |
79 Ms |
C ++ |
593b |
20:53:32 |
Poj 3061 (Binary + prefix and)