Subsequence
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8403   Accepted: 3264

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

Source

题意为:给定长度为n的整数数列以及整数S,求出总和不小于S的连续子序列的长度的最小值。假设解 不存在,输出0.

第一种方法:

先求出sum[i],从第1个数到第i个数的区间和,每次固定一个開始查找的起点sum[i],  然后採用二分查找找到 sum[i] + S 的位置,区间长度即为(末位置-(起始位置-1)),用ans保存过程中区间的最小值。时间复杂度 0(nlogn)

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn=100010;
int num[maxn];
int sum[maxn];
int n,S; int main()
{
int t;scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&S);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
sum[i]=sum[i-1]+num[i];
}
if(sum[n]<S)
{
cout<<0<<endl;
continue;
}
int ans=maxn;
for(int s=0;sum[s]+S<=sum[n];s++)//从sum[s+1]開始查找,s是開始查找的数的前一个位置
{
int t=lower_bound(sum+s+1,sum+n+1,sum[s]+S)-(sum+s);//sum+s是从第sum+s+1个地址開始查找的前一个地址,所以找到的地址减去这个地址即为区间长度
ans=min(ans,t);
}
printf("%d\n",ans);
}
return 0;
}

另外一种方法:尺取法

重复地推进区间的开头和末尾,来求满足条件的最小区间的方法称为尺取法。

主要思想为:当a1,  a2  , a3 满足和>=S,得到一个区间长度3,那么去掉开头a1,   剩下 a2,a3,推断是否满足>=S,假设满足,那么区间长度更新,假设不满足。那么尾部向后拓展,推断a2,a3,a4是否满足条件。

反复这种操作。

个人对尺取法的理解:

当一个区间满足条件时。那么去掉区间开头第一个数,得到新区间。推断新区间是否满足条件,假设不





满足条件。那么区间末尾向后扩展,直到满足条件为之。这样就得到了很多满足条件的区间,再依据题





意要求什么,就能够在这些区间中进行选择,比方区间最长,区间最短什么的。

这样跑一遍下来。时间





复杂度为O(n)。

代码:

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int maxn=100010;
int num[maxn];
int n,S; int main()
{
int t;scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&S);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
int sum=0,s=1,e=1;
int ans=n+1;
for(;;)
{
while(e<=n&&sum<S)
sum+=num[e++];
if(sum<S)
break;
ans=min(ans,e-s);
sum-=num[s++];
}
if(ans==n+1)
cout<<0<<endl;
else
cout<<ans<<endl;
}
return 0;
}

另外一种方法求区间长度的方法为 (末位置+1-起始位置)

版权声明:本文博客原创文章,博客,未经同意,不得转载。

[ACM] POJ 3061 Subsequence (仿真足)的更多相关文章

  1. poj 3061 Subsequence

    题目连接 http://poj.org/problem?id=3061 Subsequence Description A sequence of N positive integers (10 &l ...

  2. POJ - 3061 Subsequence(连续子序列和>=s的最短子序列长度)

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  3. POJ 3061 Subsequence(Two Pointers)

    [题目链接] http://poj.org/problem?id=3061 [题目大意] 给出S和一个长度为n的数列,问最短大于等于S的子区间的长度. [题解] 利用双指针获取每一个恰好大于等于S的子 ...

  4. POJ 3061 Subsequence 二分或者尺取法

    http://poj.org/problem?id=3061 题目大意: 给定长度为n的整列整数a[0],a[1],--a[n-1],以及整数S,求出总和不小于S的连续子序列的长度的最小值. 思路: ...

  5. poj 3061 Subsequence 二分 前缀和 双指针

    地址 http://poj.org/problem?id=3061 解法1 使用双指针 由于序列是连续正数 使用l r 表示选择的子序列的起始 每当和小于要求的时候 我们向右侧扩展 增大序列和 每当和 ...

  6. POJ 3061 Subsequence(尺取法)

    题目链接: 传送门 Subsequence Time Limit: 1000MS     Memory Limit: 65536K 题目描述 给定长度为n的数列整数以及整数S.求出总和不小于S的连续子 ...

  7. Poj 3061 Subsequence(二分+前缀和)

    Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12333 Accepted: 5178 Descript ...

  8. POJ 3061 Subsequence 尺取法 POJ 3320 Jessica's Reading Problem map+set+尺取法

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13955   Accepted: 5896 Desc ...

  9. POJ 3061 Subsequence 尺取法,一个屌屌的O(n)算法

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9050   Accepted: 3604 Descr ...

随机推荐

  1. li排序

    html <ul id="ul1"> <li>9</li> <li>2</li> <li>7</li& ...

  2. HTML5之Canvas影片广场

    HTML5之Canvas影片广场 1.设计源代码 <!DOCTYPE html> <head> <meta charset="utf-8" /> ...

  3. HDU 3829 Cat VS Dog

    题意: p个人  每一个人有喜欢和讨厌的动物  假设选出的动物中包括这个人喜欢的动物同一时候不包括他讨厌的动物那么这个人会开心  问  最多几个人开心 思路: 二分图最大独立集  利用人与人之间的冲突 ...

  4. 虚拟机VM10连衣裙Mac OS X 10.9.3

    最近WWDC终极大招释放--新的编程语言Swift(迅速),导致大波浪,渴望围观程序猿.当然,工欲善其事,其利润,因此,对于那些谁不Mac非常为难.可是,请放心.本文教你怎样在Windows下也能体验 ...

  5. Windows 8 键盘上推自定义处理

    原文:Windows 8 键盘上推自定义处理 在Windows 8 应用程序中,当TextBox控件获得焦点时,输入面板会弹出,如果TextBox控件处于页面下半部分,则系统会将页面上推是的TextB ...

  6. atitit.(设计模式1)--—职责链(chain of responsibility)最佳实践O7 转换日期

    atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 能够选择的模式: 表格模式,责任链模式 1 3 ...

  7. Matlab学习------------带有右键菜单的GUI学习实例

    实例步骤: 须要设置UIContextMenu,否则点击右键不显示. 右键点击第一个菜单之后:(在菜单中加入对应的回调函数) function r1_Callback(hObject, eventda ...

  8. think in coding

    ,想想除了技术还有什么? 你假设形而下的去纠结技术.仅仅会变成技术的傀儡.他们仅仅是一种表达的方式? 希望你能够形而上的去看待技术,技术千变万化,但都是为了解决这个问题的方式. 请问问自己,自己问题是 ...

  9. java中的移位运算符:<<,>>,>>>总结(转)

    java中有三种移位运算符 <<      :     左移运算符,num << 1,相当于num乘以2 >>      :     右移运算符,num >& ...

  10. 备注ocp_ORACLE专题网络

    声明:原创作品,出自 "深蓝的blog" 博客.欢迎转载.转载时请务必注明出处,否则追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanl ...