---恢复内容开始---

Subsequence
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10487   Accepted: 4337

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个一连串的数字,求不小于m的最短的连续的数字长度;
分析:暴力的话复杂度n^2,肯定会超时,有两种方法,都要掌握,第一种是lower_bound函数的使用,lower_bound的复杂度是log(n)。所以该算法的复杂度是nlog(n),相比于暴力,算法的优化仅仅体现在使用了lower_bound将n变为了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 mod = 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];   //将数组求和是常用的技巧
}
if(sum[n]<s)
{
cout<<"0"<<endl;
continue;
}
for(k=0;sum[n]-sum[k]>=s;k++)  //枚举起点
{
res=lower_bound(sum+k,sum+n+1,sum[k]+s)-(sum+k);  //第一个大于等于该值的位                                          //置
if(res<ans)
ans=res;
}
printf("%d\n",ans);
}
return 0;
}

  下面重点介绍尺取法:

  尺取法的核心思想:假设当前a[s]+s[s+1]+...a[t]是最初>=sum的,那么当s变为s+1时,即a[s+1]+s[s+2]+...a[t+n]要想仍然成为最初>=sum的,则t+n>=t(a[s]可能为0),依据这一思想,可以设置两个”指针“,一个指向p一连续序列的开头位置,另一头q指向结尾位置,该子序列之和>=sum,则当p向右推移时,则q也应向右推移直到两指针之间的序列之和再次最初>=sum,复杂度是O(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 mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
long long mid,l,r,n,m;
int a[100005];
int main()
{
int 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   尺取法   挑战146页的更多相关文章

  1. POJ 3061 Subsequence(尺取法)

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18145   Accepted: 7751 Desc ...

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

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

  3. POJ 3061 Subsequence 尺取法

    转自博客:http://blog.chinaunix.net/uid-24922718-id-4848418.html 尺取法就是两个指针表示区间[l,r]的开始与结束 然后根据题目来将端点移动,是一 ...

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

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

  5. poj 3061 题解(尺取法|二分

    题意 $ T $ 组数据,每组数据给一个长度 $ N $ 的序列,要求一段连续的子序列的和大于 $ S $,问子序列最小长度为多少. 输入样例 2 10 15 5 1 3 5 10 7 4 9 2 8 ...

  6. POJ 3061 Subsequence 尺取

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14698   Accepted: 6205 Desc ...

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

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

  8. POJ 3061 Subsequence ( 尺取法)

    题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...

  9. 题解报告:poj 3061 Subsequence(前缀+二分or尺取法)

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

  10. POJ 3061 Subsequence【二分答案】||【尺取法】

    <题目链接> 题目大意: 给你一段长度为n的整数序列,并且给出一个整数S,问你这段序列中区间之和大于等于S的最短区间长度是多少. 解题分析:本题可以用二分答案做,先求出前缀和,然后枚举区间 ...

随机推荐

  1. mysql事件(event)

    [小结]简单案例 SET GLOBAL event_scheduler=1delimiter $$ create definer = current_user event `test`.`event_ ...

  2. springboot笔记-使用JSP

    Spring Boot 项目中使用 JSP: 项目结构:需要添加webapp文件夹用来存放目录 jsp 文件 spring-boot-jsp +-src +- main +- java +- reso ...

  3. 【Usaco2014Open银组】双导航(gpsdual)

    题目 [题目描述] FJ 最近网购了一台小车.但是由于他的草率,在选择加装物品时偶然地点击了两次"Submit" ,结果最后他的小车装了两台GPS 导航系统!更糟的是,这两个系统对 ...

  4. 正则爬取某段子网站前20页段子(request库)

    首先还是谷歌浏览器抓包对该网站数据进行分析,结果如下: 该网站地址:http://www.budejie.com/text 该网站数据都是通过html页面进行展示,网站url默认为第一页,http:/ ...

  5. liunx crontab 定时访问指定url

    链接主机 crontab -e 打开文件,直接输入需要执行的脚本 1 9 * * * /usr/bin/curl http://www.baidu.com 语法解析 * * * * * /usr/bi ...

  6. Ansible 常用模块详解

    经过前面的介绍,我们已经熟悉了 Ansible 的一些常识性的东西和如何编译安装Ansible,从本章开始我们将全面介绍 Ansible 的各种生产常用模块,这些也是我们使用 Ansible 的过程中 ...

  7. linux系统内核优化参数

    1. 系统连接数优化 # vim /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 * soft noproc 655 ...

  8. java 给定一个日期期间 返回形如Mar 2015 3/20-3/31的数据

    最近一个项目中有个前台对于表头要求: 给定一个日期期间返回形如 Mar 2015 3/20-3/31Apr 2015 4/1-4/30 这样的月年数据,简单的写了下代码,暂时没想到更好的办法 例如传进 ...

  9. 09 Scrapy框架以及基本使用

    一.什么是scrapy? 是为了爬取网站数据,提取结构性数据而编写的应用框架.之所以叫做框架是因为集成了各种实用功能(高性能异步下载,队列,分布式,解析,持久化等等)的项目模板.对于框架的学习,重点是 ...

  10. PAT Basic 1001 害死人不偿命的(3n+1)猜想 (15 分)

    卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ( 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 年的世界 ...