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. Autofac 入门

    Autofac 入门文档 原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: ...

  2. ASP.NET执行循序

    首先第一次运行一个应用程序(WebSite或者WebApplication都是Web应用程序)第一次请求 -> 1,IIS -> 2,aspnet_isapi(非托管dll) -> ...

  3. oracle dblink造成远程数据库session过多

    现场报网公司数据库连不上,先检查了下数据库processes=1500,session=2200.我认为非常大啊.这个数据库没有几个人用. 查看v$session中的session最多是哪个machi ...

  4. Android - 分享内容

    Android程序一个很重要地特性是他们可以相互通讯和交互.为什么要重新开发那些不是你程序的核心而且其他程序已经有的功能呢? 这里将要介绍一些使用Intent API和ActionProvider对象 ...

  5. Mysql入门到精通数据表的操作

    变更表 ALTER TABLE tb_name; 1.加入场 ALTER TABLE tb_name ADD 字段名字 字段类型 约束条件 [FIRST/AFTER 字段名称] 1>加入user ...

  6. Chapter 1 Securing Your Server and Network(12):保护链接server

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/38438363.专题文件夹:http://blog.csdn.net/dba_huangz ...

  7. table在 点击线条颜色

    效果图: <html> <head> <meta http-equiv="Content-Type" content="text/html; ...

  8. 给AspNetPager分页控件添加bootstrap样式

    AspNetPager分页控件算是比较好用的一个分页控件了.想要结合bootstrap使用,官方代码入口 .pagination a[disabled]{ color: #777;cursor: no ...

  9. 跨域 Iframe 通信解决方案(兼容 IE 系列浏览器。)

    实现思路: 1.postMessage(IE8+, Firefox 3.1+, Opera 9+, Safari, and Chrome) 2.利用window.navigator共享信息,使支持IE ...

  10. Android系统关机或几种方式重启

    ---------------------------------------------------------------------------------------------------- ...