---restore content starts---
subsequence
| Time Limit: 1000MS |
|
Memory Limit: 65536K |
| Total Submissions: 10487 |
|
Accepted: 4337 |
Description
a sequence of n positive integers (< n <), each of the them less than or equal 10000, and A positive inte Ger S (S <) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is Greater than or equal to S.
Input
The first line is the number of test cases. The program have to read the numbers N and S, separated by a interval, from the first line. The numbers of the sequence is given in the second line of the "test case", separated by intervals. The input would finish with the end of file.
Output
The the program have to print the result on separate line of the output File.if no answer, print 0.
Sample Input
210 155 1 3 5 10 7 4 9 2 85 111 2 3 4 5
Sample Output
23
Source
Southeastern Europe 2006Test Instructions: give you n a series of numbers, not less than the shortest continuous digital length of M; analysis: Violent words of complexity n^2, certainly will time out, there are two ways to master, The first is the use of the Lower_bound function, and the complexity of the lower_bound is log (n). So the complexity of the algorithm is Nlog (n), compared to violence, the optimization of the algorithm is only reflected in the use of Lower_bound n into log (n).
#include <cstdio> #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib > #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <set >using namespace std; #define MM (a) memset (A,0,sizeof (a)) typedef long Long ll;typedef unsigned long long ull;const int m od = 1000000007;const Double EPS = 1e-10;const int inf = 0x3f3f3f3f;long long mid,l,r,n,m;int sum[100005];int main () { int n,cas,s,k,ans,res; cin>>cas; while (cas--) {scanf ("%d%d", &n,&s); sum[0]=0;ans=100005; for (int i=1;i<=n;i++) {scanf ("%d", &sum[i]); SUM[I]+=SUM[I-1]; Summing the array is a common technique} if (sum[n]<s) {cout<< "0" <<endl; Continue } for (k=0;sum[n]-sum[k]>=s;k++)//Piece lift point {res=lower_bound (sum+k,sum+n+1,sum[k]+s)-(sum +K); //first oneA bit greater than or equal to the value//set if (Res<ans) ans=res; } printf ("%d\n", ans); } return 0;}
The following emphasis is on the ruler extraction:
The core idea of the ruler method: assuming the current a[s]+s[s+1]+ ... A[t] is originally >=sum, then when S becomes s+1, that is a[s+1]+s[s+2]+ ... A[t+n] to be still the original >=sum, then T+n>=t (A[s] may be 0), according to this idea, you can set two "pointer", a point to the beginning of a continuous sequence of p, the other end of the Q point, the sum of >=sum, when P goes right, Then Q should also move to the right until the sum of the sequence between the two pointers is initially >=sum, and the complexity is O (n), in fact, the most significant advantage of the ruler method is that it can save the results of the intermediate molecular sequence, which is also the reason for its lower complexity.
#include <cstdio> #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib > #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <set >using namespace std; #define MM (a) memset (A,0,sizeof (a)) typedef long Long ll;typedef unsigned long long ull;const int m od = 1000000007;const Double EPS = 1e-10;const int inf = 0x3f3f3f3f;long long mid,l,r,n,m;int a[100005];int main () {in T n,cas,s; cin>>cas; while (cas--) {scanf ("%d%d", &n,&s); a[0]=0;a[n+1]=0; for (int i=1;i<=n;i++) scanf ("%d", &a[i]); int p=0,q=0,v=0,ans=n+1; while (v<s&&q<=n) {q++; V+=A[Q]; } if (q==n+1) {cout<< "0" <<endl; Continue } for (;;) {while (v<s&&q<=n) { q++; V+=A[Q]; } if (q==n+1) break; if (ans>q-p) ans=q-p; p++; V-=A[P]; } printf ("%d\n", ans); } return 0;
POJ 3061 subsequence-scale Challenge 146 page