题目

给定一个数组和一个数s,在这个数组中找一个区间,使得这个区间之和等于s。

例如:给定的数组int x[14] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};和一个s = 15。那么,可以找到的区间就应该有0到4, 3到5, 6到7.(注意这里的下标从0开始)

思路

对于这样的题,不用任何技巧就可以跑出结果,例如下面这个方法可能是大多数人能够想出来的:

先用一个数组sum[i]存放前i个元素的和,其实现用的是”递推思想“,注意,在编程中”递推“的思想用的特别多,一定要习惯这种思维方式。

sum[0] = x[0];//x为给定的原数组
for(int i = 1; i < n; i++){
sum[i] += sum[i-1];//递推思想
}

然后通过两层循环求解

for(int i = 0; i < n; i++)
for(int j = n-1; j >= 0; j--){
if(sum[j]-sum[i]==s) printf("%d---%d\n", i, j);
}

上面的方法当然是可行的,但是复杂度太高,有一个算法可以将其复杂度降为O(n)。这就是”尺取算法“。

尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。之所以需要掌握这个技巧,是因为尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的。

那么,用”尺取法“做上面这道题思路应该是这样的:

其实,这种方法很类似于蚯蚓的蠕动。

1)用一对脚标i, j。最开始都指向第一个元素。

2)如果区间i到j之和比s小,就让j往后挪一位,并把sum的值加上这个新元素。相当于蚯蚓的头向前伸了一下。

3)如果区间i到j之和比s大,就让sum减掉第一个元素。相当于蚯蚓的尾巴向前缩了一下。

4)如果i到j之和刚好等于s,则输入。

实现

#include<iostream>
#include<cstdio>
using namespace std; void findSUM(int *A, int n, int s){
int i = 0, j = 0;
int sum = A[0];
while(i <= j && j < n){
if(sum >= s){
if(sum == s) printf("%d---%d\n", i, j);
sum -= A[i];
i++;
}
else{
j++;
sum += A[j];
}
}
} int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int m;
int x[14] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
cin >> m;
findSUM(x, 14, m); return 0;
}

ACM-学习记录-尺取法的更多相关文章

  1. HDU 6205(尺取法)2017 ACM/ICPC Asia Regional Shenyang Online

    题目链接 emmmm...思路是群里群巨聊天讲这题是用尺取法.....emmm然后就没难度了,不过时间上3000多,有点.....盗了个低配本的读入挂发现就降到2800左右, 翻了下,发现神犇Clar ...

  2. 树形DP+RMQ+尺取法 hdu4123

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 参考博客:两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race ...

  3. HDU 6119 小小粉丝度度熊 【预处理+尺取法】(2017"百度之星"程序设计大赛 - 初赛(B))

    小小粉丝度度熊 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  4. Codeforces 958F2 Lightsabers (medium) 尺取法

    题目大意: 输入n,m,分别表示人的个数和颜色的个数,下一行输入n个数,对应每个人的颜色,最后一行输入对应每个颜色的人应有的数量: 问是否能找出一个区间,满足条件但有多余的人,输出多余的人最少的个数, ...

  5. nyoj133_子序列_离散化_尺取法

    子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...

  6. POJ 3061 (二分+前缀和or尺取法)

    题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点 ...

  7. POJ 3320 尺取法,Hash,map标记

    1.POJ 3320 2.链接:http://poj.org/problem?id=3320 3.总结:尺取法,Hash,map标记 看书复习,p页书,一页有一个知识点,连续看求最少多少页看完所有知识 ...

  8. 【POJ 3320】Jessica's Reading Problemc(尺取法)

    题 题意 P个数,求最短的一段包含P个数里所有出现过的数的区间. 分析 尺取法,边读边记录每个数出现次数num[d[i]],和不同数字个数n个. 尺取时,l和r 代表区间两边,每次r++时,d[r]即 ...

  9. [CF660C]Hard Process(尺取法)

    题目链接:http://codeforces.com/problemset/problem/660/C 尺取法,每次遇到0的时候补一个1,直到补完或者越界为止.之后每次从左向右回收一个0点.记录路径用 ...

  10. Codeforces Round #364 (Div.2) C:They Are Everywhere(双指针/尺取法)

    题目链接: http://codeforces.com/contest/701/problem/C 题意: 给出一个长度为n的字符串,要我们找出最小的子字符串包含所有的不同字符. 分析: 1.尺取法, ...

随机推荐

  1. 【jmeter】请求域名解析失败,添加本地代理

    jmeter HTTP请求URL中使用域名 http://xxx.xxx.xxx,异常:java.net.UnkownHostException 原因:请求域名没有被解析成功,该http请求没有通过本 ...

  2. Liunx安装Docker

    1.更新yum包到最新 sudo yum update 2.卸载历史Docker,如果没有安装过,则跳过该步 sudo yum remove docker \ docker-client \ dock ...

  3. Redis Template部分接口学习记录

    Redis Template是操作redis的一个封装模板,让我们更加简便的去操作redis. 操作键类型的接口: GeoOperations Redis的地理空间操作,如GEOADD,GEORADI ...

  4. sync同步工具使用

    sync详解 sync概述: rsync是一个提供快速增量文件传输的开源工具.rsync在GNU通用公共许可证下免费提供,目前由Wayne Davison维护.传输前进行压缩,适合做备份使用. 命令格 ...

  5. vue上传图片组件

      <template> <!-- 上传控件 用法: <upload-widget v-model="imgUrl"></upload-widg ...

  6. 关于IllegalMonitorStateException异常的解释之一

    注意 在同步控制方法或同步控制块里调用wait(),notify()和notifyAll().如果在非同步控制方法里调用这些方法,程序能通过编译,但运行的时候,将得到IllegalMonitorSta ...

  7. Spring Boot中使用过滤器和拦截器

    过滤器(Filter)和拦截器(Interceptor)是Web项目中常用的两个功能,本文将简单介绍在Spring Boot中使用过滤器和拦截器来计算Controller中方法的执行时长,并且简单对比 ...

  8. Java的流程控制

    Scanner对象 next(); 一定要读取到有效字符后才可以结束输入. 对输入有效字符之前遇到的空白,next()方法会自动将其去掉(). 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束 ...

  9. 荔枝派Licheepi nano裸机移植ZLG_GUI和3D旋转立方体

    一:前言 以前申请到了荔枝派zero,在发了两个开箱贴后就放在一边吃灰了.后来又购买了荔枝派nano,刷了几个教程中的系统之后又放到一边吃灰了.虽然有屯板子的习惯,却没有使用板子的能力. 后来,经过断 ...

  10. axel多线程下载

    Axel 是一个轻量级下载程序,它和其他加速器一样,对同一个文件建立多个连接,每个连接下载单独的文件片段以更快地完成下载. Axel 通过打开多个 HTTP/FTP 连接来将一个文件进行分段下载,从而 ...