Subsequence poj 3061 二分(nlog n)或尺取法(n)

Subsequence

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9236   Accepted: 3701

Description

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) 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. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

Sample Output

2
3

二分代码:
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <string>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 #include <queue>
11 #include <stack>
12 #include <sstream>
13 #include <iomanip>
14 using namespace std;
15 const int INF=0x4fffffff;
16 const int EXP=1e-6;
17 const int MS=100005;
18
19 int a[MS];
20 int sum[MS];
21 int N,S;
22
23 int main()
24 {
25       int T;
26       scanf("%d",&T);
27       while(T--)
28       {
29             scanf("%d%d",&N,&S);
30             sum[0]=0;
31             a[0]=0;
32             for(int i=1;i<=N;i++)
33             {
34                   scanf("%d",&a[i]);
35                   sum[i]=a[i]+sum[i-1];
36             }
37             if(sum[N]<S)
38             {
39                   printf("0\n");
40                   continue;
41             }
42             int ans=N;
43             for(int i=1;sum[i-1]+S<=sum[N];i++)
44             {
45                   int index=lower_bound(sum+i,sum+N,sum[i-1]+S)-sum;
46                   ans=min(ans,index-i+1);
47             }
48             printf("%d\n",ans);
49       }
50       return 0;
51 }

尺取大法好啊

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <string>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 #include <queue>
11 #include <stack>
12 #include <sstream>
13 #include <iomanip>
14 using namespace std;
15 const int INF=0x4fffffff;
16 const int EXP=1e-6;
17 const int MS=100005;
18
19 int a[MS];
20 int N,S;
21
22 int main()
23 {
24       int T;
25       scanf("%d",&T);
26       while(T--)
27       {
28             scanf("%d%d",&N,&S);
29             for(int i=0;i<N;i++)
30                   scanf("%d",&a[i]);
31             int sum=0;
32             int s=0,t=0;
33             int ans=N+1;
34             while(1)
35             {
36                   while(t<N&&sum<S)
37                         sum+=a[t++];
38                   if(sum<S)
39                         break;
40                   ans=min(ans,t-s);
41                   sum-=a[s++];
42             }
43             if(ans>N)
44                   printf("0\n");
45             else
46                   printf("%d\n",ans);
47       }
48       return 0;
49 }
时间: 2025-01-05 23:05:48

Subsequence poj 3061 二分(nlog n)或尺取法(n)的相关文章

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

poj 3320 Jessica&#39;s Reading Problem (尺取法)

Jessica's Reading Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8787   Accepted: 2824 Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent littl

POJ 3320 Jessica&#39;s Reading Problem 尺取法/map

Jessica's Reading Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7467   Accepted: 2369 Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent littl

POJ 3061 (二分+前缀和)

题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点慢. 二分枚举序列长度,如果可行,向左找小的,否则向右找大的. 前缀和预处理之后,可以O(1)内求和. #include "cstdio" #include "cstring" int sum[100005],n,s,a,T; bool check(int x) { i

POJ3061 Subsequence(二分前缀和法+尺取法)

二分+前缀和法 满足条件的子序列长度在(0,n)之间,sum[x+i]-sum[i]为从从第i个元素开始序列长度为x的元素的和.前缀和可在O(n)的时间内统计 sum[i]的值.再用二分找出满足条件的最小的子序列长度. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #

Subsequence POJ - 3061

Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22040   Accepted: 9404 Description A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) ar

poj 2566Bound Found(前缀和,尺取法)

http://poj.org/problem?id=2566: 题意:找连续的串,求和绝对值与所给数字最接近的串. 思路:先求下标为1的到其他下的串的值,也就是前缀和:这样可以在O(1)的时间内求出各个串的和.比如S1(1,1),S3(1,3); 那么S3-S1就是S(2,3): 然后对上面所求的前缀和按从小到大排序.(因为取的是绝对值所以abs(Sn-Sk)==abs(Sk-Sn)); 这样就可以用尺取法去做了.复杂度为O(n); 还可以用二分取找值,复杂度为O(n*log(n)); 1 #i

POJ 3061 Subsequence (二分||尺取法)

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequen

POJ 3061 Subsequence ( 二分 || 尺取法 )

题意 : 找出给定序列长度最小的子序列,子序列的和要求满足大于或者等于 S,如果存在则输出最小长度.否则输出 0(序列的元素都是大于 0 小于10000) 分析 : 有关子序列和的问题,都可以考虑采用先构造前缀和的方式来进行接下来的操作 ( 任意子序列的和都能由某两个前缀和的差表示 ). 二分做法 ==> 我们枚举起点,对于每一个起点 St 二分查找看看 St 后面有没有前缀和是大于或者等于 [ St的前缀和 ] + S 的,如果有说明从当前起点开始有一个终点使得起终之和是大于或者等于 S 的,