取尺法(算法)

 1 /*常用的解题技巧:尺取法
 2  尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。之所以需要掌握这个技巧,是因为尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的
 3        时候,所以尺取法是一种高效的枚举区间的方法,一般用于求取有一定限制的区间个数或最短的区间等等。当然任何技巧都存在其不足的地方,有些情况下尺取法不可行,无法得出正确答案。
 4        使用尺取法时应清楚以下四点:
 5  1、什么情况下能使用尺取法?      2、何时推进区间的端点?     3、如何推进区间的端点?     3、何时结束区间的枚举?
 6    尺取法通常适用于选取区间有一定规律,或者说所选取的区间有一定的变化趋势的情况,通俗地说,在对所选取区间进行判断之后,我们可以明确如何进一步有方向地推进区间端点以求解满足条件的区间,如果已经判断了目前所选取的区间,但却无法确定所要求解的区间如何进一步
 7    得到根据其端点得到,那么尺取法便是不可行的。首先,明确题目所需要求解的量之后,区间左右端点一般从最整个数组的起点开始,之后判断区间是否符合条件在根据实际情况变化区间的端点求解答案。*/
 8
 9   /*题目大意(poj 3061):
10  本题的意思是在保持原来顺序不变的条件下,求得几个连续元素之和大于S的最短序列长度。以第一组数据为例:
11               10 15
12               5 1 3 5 10 7 4 9 2 8
13           求第n项与前n项之和得:5 6 9 14 24 31 35 44 46 54 (记为a[i])
14          t=a[i-1]-s,在序列中小于t的长度为n,a[i-1]到开始位置的长度为m,则在原始序列中由a[i-1]开始向前推长度为m-n+1的数8 2 9之和大于15,长度为3,依次往下推,求出最短长度。*/
15
16 #include<iostream>
17 #include<cstdio>
18 #define min(a,b) (a<b?a:b)
19 #define max(a,b) (a>b?a:b)
20 using namespace std;
21 const int MAXN=1e5;
22 int N,S;
23 int a[MAXN+1];
24 int num;
25 void solve() {
26     int res=N+1;
27     int s=0,t=0,sum=0;
28     while(true) {
29         while(t<N&&sum<S)
30             sum+=a[t++];
31         if(sum<S)
32             break;
33         res=min(res,t-s);
34         sum-=a[s++];
35     }
36     if(res>N)
37     res=0;
38     cout<<res<<endl;
39 }
40 int main() {
41     cin>>num;
42     for(int tmp=1;tmp<=num;tmp++) {
43         int i=1;
44          cin>>N>>S;
45          for(i=1;i<=N;i++)
46              cin>>a[i];
47           solve();
48        }
49     return 0;
50 }

时间 内存 结果 语言
79 596K Accepted C++
时间: 2024-10-28 22:46:54

取尺法(算法)的相关文章

怎样用取尺法处理连续区间内数字同样

常常会遇到类似以下这样的问题: 给你n个数.由0和1组成,问1或者0的最大连续长度是多少 110001101的最大连续长度就是中间3个连续的0.所以是3 这里略微总结出了一个取尺法,以后遇到这种题目就不须要再思考太多细节了 int L, R = 1, ans = 0; for(L = 1; L <= n; L = R + 1) { for(R = L; R + 1 <= n && B[L] == B[R + 1]; R++); ans = max(ans, R - L + 1)

如何用取尺法处理连续区间内数字相同

经常会遇到类似下面这种问题: 给你n个数,由0和1组成,问1或者0的最大连续长度是多少 110001101的最大连续长度就是中间3个连续的0,所以是3 这里稍微总结出了一个取尺法,以后遇到这样的题目就不需要再思考太多细节了 int L, R = 1, ans = 0; for(L = 1; L <= n; L = R + 1) { for(R = L; R + 1 <= n && B[L] == B[R + 1]; R++); ans = max(ans, R - L + 1)

计蒜客第五场 UCloud 的安全秘钥(中等) (尺取游标法

每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作.作为一家安全可信的云计算平台,秘钥的安全性至关重要.因此,UCloud 每年会对用户的秘钥进行安全性评估,具体的评估方法如下: 首先,定义两个由数字序列组成的秘钥 aa 和 bb近似匹配(\approx≈) 的关系.aa 和 bb 近似匹配当且仅当同时满足以下两个条件: |a|=|b|∣a∣=∣b∣,即 aa 串和 bb 串长度相等. 对于每种数字 cc,cc 在 aa 中出现的次数等于 cc 在 bb 中出现的次

php 二分查找法算法详解

一.概念:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 二.代

poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)

Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30529   Accepted: 8033 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Y

快速排序之三数取中法

---恢复内容开始--- 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 基本步骤 三数取中 在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分.在此我们采用三数取中法,也就是取左端.中间.右端三个数,然后进行排序,将中间数作为枢纽值. 根据枢纽

【实操】进制转换:除基倒取余法

一.原理:除基倒取余法 以10进制转2进制为例:输入一个十进制数n,每次用n除以2,把余数记下来,再用商去除以2...依次循环,直到商为0结束,把余数倒着依次排列,就构成了转换后的二进制数. 所有进制之间的转换都是如此,2可以换成任何数字.十进制转二进制.八进制.十六进制.64进制,全部如下. 二.具体的JAVA实现: 2.1 10进制数字转n进制: public class Main { public static void main (String[] args) { int n = 64;

两个数组取交集的算法

在Lucene中,如果用户的查询向量Term t = {xx,xx,……},BooleanQuery为AND时,每个t---->对应得到的倒排列表,倒排列表由许多的倒排索引项构成,然后取其中重复的文档编号,然后进行排序.器核心思想类似于如下问题: 现有两个数组:int []data1 = {12,45,65,2,5} int []data2 = {12,5,-8,9},取其中的交集. 实现的方案有很多,现在采取一种时间和空间相对较好的算法:集合压缩算法,即:1.分别计算两个数组的min和max(

算法设计与分析——回溯法算法模板

以深度优先方式系统搜索问题解的算法称为回溯法.在回溯法中,解空间树主要分为了四种子集树.排列树.n叉树和不确定树. 在<算法设计与分析课本>中介绍了11个回溯法的问题样例,这里根据解空间树的类型做一个分类. 子集树 装载问题 符号三角形问题 0-1背包问题 最大团问题 算法模板: void backtrack(int t) { if(搜索到叶子结点) { return; } for(i=0; i<=1; i++) //01二叉树 { if(满足约束函数和限界函数)//剪枝 { backt