Subsequence

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 18795 Accepted: 8043

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. 题意就是给你n个数,要你选择连续的一段区间,其总和不小于s,问你最短的区间长度是多少。
  2. 尺取法的模板题,尺取法很有意思,也被称之为尺取虫,这个可以说是很形象了,可以看成是一个一定长度的虫在线性表中爬动,复杂度就是O(N)。关于尺取有很多种写法,不同的写法复杂度不同,这里讲三种写法
    • 第一种就是二分加尺取法,首先二分出一个长度,然后用尺取法去数组中检验这个二分出来的总和,复杂度为O(NlogN)。
    • 第二种感觉和尺取关系不大,用的是二分,先求出前缀和,以每一个前缀和为起点,当前前缀和+s为终点,因为前缀和是一个递增的数列,所以就可以二分查找终点,然后得到长度。复杂度为O(NlogN)。
    • 第三种就是尺取,只不过这个尺取虫的长度是可以变换的,我们找一个最小的长度就行了,从起点开始每次保证尺取范围的总和不小于s,同时向后面移动。复杂度为O(N).

第一种尺取代码

#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 1e5+10; int num[maxn],n,s; void init() {
scanf("%d%d",&n,&s);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
} bool checke(int len) {
int sum = 0;
for(int i=0;i<len;i++)
sum += num[i];
if(sum >= s)
return true;
int l = 0,r = len-1;
while(r < n) {//
sum -= num[l];
l++,r++;
sum += num[r];
if(sum >= s)
return true;
}
return false;
} int binary_search() {//二分尺取虫的长度
int l = 1 ,r = n;
while(r - l > 1) {
int mid = (l + r) >> 1;
if(checke(mid))
r = mid;
else
l = mid;
}
return r;
} bool check_ans() {
int sum = 0;
for(int i=0;i<n;i++)
sum += num[i];
if(sum < s)
return true;
return false;
} int main() {
int t;
scanf("%d",&t);
while(t--) {
init();
if(check_ans()) {//如果总和都小于s直接输出0
printf("0\n");
continue;
}
int ans = binary_search();
printf("%d\n", ans);
}
return 0;
}

第二种写法代码:

#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 1e5+10; int sum[maxn],n,s; void init() {
scanf("%d%d",&n,&s);
for(int i=1;i<=n;i++) {
int temp;
scanf("%d",&temp);
sum[i] = sum[i-1]+temp;
}
} int solve() {
int ans = 0x7f7f7f7f;
for(int i=0;sum[i]+s<=sum[n];i++) {
int last = sum[i] + s;
int pos = lower_bound(sum+i,sum+n+1,last) - sum;//就是一个二分查找
int len = pos - i;
ans = min(ans,len);
}
return ans;
} int main() {
int t;
scanf("%d",&t);
while(t--) {
init();
int ans = solve();
if(sum[n] < s)
ans = 0;
printf("%d\n",ans);
}
return 0;
}

第三种写法代码:

#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 1e5+10; int n,s,num[maxn]; int main() {
int t;
scanf("%d",&t);
while(t--) {
int sum,l,r,ans;
sum = l = r = 0;
ans = 0x7f7f7f7f;
scanf("%d%d", &n, &s);
for (int i = 0; i < n; i++)
scanf("%d", &num[i]);
while (1) {
while (sum < s && r < n) {
sum += num[r++];
}
if (sum < s)
break;
ans = min(ans, r - l);
sum -= num[l++];
}
if (ans > n)
ans = 0;
printf("%d\n",ans);
}
return 0;
}

POJ:3061-Subsequence(尺取法模板详解)的更多相关文章

  1. POJ 3061 Subsequence(尺取法)

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

  2. POJ 3061 Subsequence 尺取法

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

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

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

  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. C++模板详解

    参考:C++ 模板详解(一) 模板:对类型进行参数化的工具:通常有两种形式: 函数模板:仅参数类型不同: 类模板:   仅数据成员和成员函数类型不同. 目的:让程序员编写与类型无关的代码. 注意:模板 ...

  8. 25.C++- 泛型编程之函数模板(详解)

    本章学习: 1)初探函数模板 2)深入理解函数模板 3)多参函数模板 4)重载函数和函数模板 当我们想写个Swap()交换函数时,通常这样写: void Swap(int& a, int&am ...

  9. 26.C++- 泛型编程之类模板(详解)

    在上章25.C++- 泛型编程之函数模板(详解) 学习了后,本章继续来学习类模板   类模板介绍 和函数模板一样,将泛型思想应用于类. 编译器对类模板处理方式和函数模板相同,都是进行2次编译 类模板通 ...

随机推荐

  1. MySQL(四)

    一.使用正则表达式查询 SELECT * FROM employee WHERE name REGEXP '^ale'; SELECT * FROM employee WHERE name REGEX ...

  2. Python列表边遍历边修改问题解决方案:alist[:]

    最近在看python,遇到个简单的问题:删除列表中指定的重复元素,发现一些实用并且有趣的东西. 1.错误示范 alist = [1,1,2,2,3,3,2,2,1,1] for i in alist: ...

  3. DXperience Winforms新版本13.2功能预览

    据界面控件厂商 DevExpress 官方最新消息,大家期盼已久的DXperience 13.2终于要面世了.今天在这里提前跟大家提前披露一下DXperience Winforms 13.2的一些精彩 ...

  4. BarCode条形码生成库

    一.Barcode生成条形码的类库 二.示例 新建mvc空项目,添加Nuget引用 主要代码 // // GET: /Home/ public FileContentResult Index() { ...

  5. 诸葛io | 精细化运营分析解决方案

    类型: 定制服务 软件包: business intelligence internet media solution collateral 联系服务商 产品详情 解决方案 概要 数据监测 ? 异常发 ...

  6. $("#Upfile").MultiFile();

    Jquery的multifile 1.多文件上传: 2.如上几个验证不重复,和限制上传数量的验证显示的是英文,改成中文文本时,如果不用国标解码,到时候提示框会出现乱码现象.所以一般需要中文显示的时候, ...

  7. Node.js-sublime text3 配置node.js(ERROR: The process "node.exe" not found.)

    默认已经安装好sublime.node和npm 1.sublime的node.js插件下载 由于在package control上经常下载失败,所以这里直接从GitHub上进行下载! GitHub下载 ...

  8. BZOJ 4679/Hdu5331 Simple Problem LCT or 树链剖分

    4679: Hdu5331 Simple Problem 题意: 考场上,看到这道题就让我想起BZOJ4712洪水.然后思路就被带着飞起了,完全没去考虑一条链的情况,于是GG. 解法:先考虑一条链的做 ...

  9. 你真的会用ABAP, Java和JavaScript里的constructor么?

    如果constructor里调用了一个成员方法,这个方法被子类override了,当初始化一个子类实例时,父类的构造函数被的调用,此时父类构造函数的上下文里调用的成员方法,是父类的实现还是子类的实现? ...

  10. 设定网页最小最大宽度和高度(兼容IE6)

    http://www.cnblogs.com/double-bin/archive/2011/12/19/2293093.html /* 最小寬度 */ .min_width{min-width:30 ...