B - Bound Found POJ - 2566(尺取 + 对区间和的绝对值
B - Bound Found POJ - 2566
Signals of most probably extra-terrestrial origin have been received
and digitalized by The Aeronautic and Space Administration (that must
be going through a defiant phase: “But I want to use feet, not
meters!”). Each signal seems to come in two parts: a sequence of n
integer values and a non-negative integer t. We’ll not go into
details, but researchers found out that a signal encodes two integer
values. These can be found as the lower and upper bound of a subrange
of the sequence whose absolute value of its sum is closest to t.You are given the sequence of n integers and the non-negative target
t. You are to find a non-empty range of the sequence (i.e. a
continuous subsequence) and output its lower index l and its upper
index u. The absolute value of the sum of the values of the sequence
from the l-th to the u-th element (inclusive) must be at least as
close to t as the absolute value of the sum of any other non-empty
range. Input The input file contains several test cases. Each test
case starts with two numbers n and k. Input is terminated by n=k=0.
Otherwise, 1<=n<=100000 and there follow n integers with absolute
values <=10000 which constitute the sequence. Then follow k queries
for this sequence. Each query is a target t with 0<=t<=1000000000.
Output For each query output 3 numbers on a line: some closest
absolute sum and the lower and upper indices of some range where this
absolute sum is achieved. Possible indices start with 1 and go up to
n.
Sample Input
5 1
-10 -5 0 5 10
3
10 2
-9 8 -7 6 -5 4 -3 2 -1 0
5 11
15 2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
15 100
0 0
Sample Output
5 4 4
5 2 8
9 1 1
15 1 15
15 1 15
思路
- 题意:这一题就是给你一个有正有负数的序列ar[],然后又给我们一个 值val
问能否在这个ar序列中找到一个子串,是这个子串的数字和的绝对值 最接近 val 的那个子串 - 思路:这一题思路真实很神奇,也很有用,首先求这个序列的前缀和,并对这个前缀和(注意这个前缀合是由结构体组成、存有当前前缀和终点位置的id下标)按从小到大的顺序排序,这样我们就的得到一个有序的前缀和序列br,
由于我们让求的是一个区间和的绝对值
,所以我们让br中任意两个位置的前缀和相减(大位置 - 小位置的前缀和),我们就能得到任意的 子区间 和;之后要做的就是用 尺取 不断的维护最接近val 的子区间了,- 在尺取的时候有一点细节要明白,我们尺取某个区间的时候,我们假设这个区间前缀的差值为tem,,,当tem <= val 这个时候r(尺取是的有边界)要 ++,当tem > val 的时候就没有必要 r++了,
因为在++,只会让tem更大、更不接近val
,所这个时候我们要 l ++,去减小区间前缀和差值,
- 在尺取的时候有一点细节要明白,我们尺取某个区间的时候,我们假设这个区间前缀的差值为tem,,,当tem <= val 这个时候r(尺取是的有边界)要 ++,当tem > val 的时候就没有必要 r++了,
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int Len = 1e5+10;
struct Node
{
int sum,id;
bool operator < (const Node x) const
{
return sum < x.sum;
}
} a[Len];
int main()
{
//freopen("A.txt","r",stdin);
int n,t;
while(scanf("%d %d", &n, &t) && n + t)
{
a[0].id = 0, a[0].sum = 0;
for(int i = 1; i <= n; i ++)
{
scanf("%d", &a[i].sum);
a[i].sum += a[i - 1].sum;
a[i].id = i;
}
sort(a, a + 1 + n);
while(t --)
{
int val;
scanf("%d", &val);
int l = 0, r = 1, mn = 1e9 + 7, al, ar, sum;
while(true)
{
while(r <= n) //小于n之前的任意一对的值我们都要统计一下
{
int tem = a[r].sum - a[l].sum; //获取区间和的差值
if(abs(tem - val) < mn) //判断这个区间和的差值是否跟接近 val,通过小于原来的最优值值来判断
{
mn = abs(tem - val);
sum = tem;
al = min(a[r].id, a[l].id) + 1; //注意:左边界 +1
ar = max(a[r].id, a[l].id);
}
if(tem < val) //如果当前值还是小于要靠近的值,那么我们增大区间和的差值来 缩小与给定值的差值,并且继续循环看能否更新最优值
r ++;
else
break;
}
if(r > n) break; //到达边界结束
l ++;
if(l == r) r ++; //如果 l == r ,这种情况不符合讨论的情况 让 r ++
}
printf("%d %d %d\n", sum, al, ar);
}
}
return 0;
}
总结
1.当让我们求某个区间的和的绝对值
大小时,我们可以求 前缀,在对这个前缀可排序(这个前缀要保留 id位置的),这数据变的有序了我们更容易处理问题
2.确定好 我们尺取 维护的是 那个值、什么值
B - Bound Found POJ - 2566(尺取 + 对区间和的绝对值的更多相关文章
- A - Jessica's Reading Problem POJ - 3320 尺取
A - Jessica's Reading Problem POJ - 3320 Jessica's a very lovely girl wooed by lots of boys. Recentl ...
- POJ 2566 尺取法(进阶题)
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4297 Accepted: 1351 Spe ...
- Greedy:Bound Found(POJ 2566)
神奇密码 题目大意:就是给你一个数组,要你找出连续的数的绝对值的和最接近t的那一串,并且要找出数组的上界和下界的下标,并显示他们的和 因为这一题的数有正有负,所以必须要先把和求出来,然后排序,然 ...
- POJ 2566 Bound Found 尺取 难度:1
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1651 Accepted: 544 Spec ...
- poj 2566 Bound Found 尺取法
一.首先介绍一下什么叫尺取 过程大致分为四步: 1.初始化左右端点,即先找到一个满足条件的序列. 2.在满足条件的基础上不断扩大右端点. 3.如果第二步无法满足条件则到第四步,否则更新结果. 4.扩大 ...
- 尺取法 poj 2566
尺取法:顾名思义就是像尺子一样一段一段去取,保存每次的选取区间的左右端点.然后一直推进 解决问题的思路: 先移动右端点 ,右端点推进的时候一般是加 然后推进左端点,左端点一般是减 poj 2566 题 ...
- POJ 2566:Bound Found(Two pointers)
[题目链接] http://poj.org/problem?id=2566 [题目大意] 给出一个序列,求一个子段和,使得其绝对值最接近给出值, 输出这个区间的左右端点和区间和. [题解] 因为原序列 ...
- poj 2566 Bound Found
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4384 Accepted: 1377 Spe ...
- Bound Found(思维+尺取)
Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronaut ...
随机推荐
- 18 JpaRepository和JpaSpecificationExecutor
继承JpaRepository后的方法列表 JpaRepository findAll() List<T> findAll(Sort) List<T> findAll(Iter ...
- 三维GIS引擎地图可视化渲染方案设计
1.GIS地图可视化流程 GIS地图可视化就是将空间数据转化为地图数据再进行交互处理的方法,下图一展示了地图可视化的可编程渲染的典型管道,原始空间数据必须处理为图形API支持基础图元用以地图渲染.下图 ...
- flask 设置https请求 访问flask服务器
学习过程中想要学教程中一样,做个假的微信公众号推送,不过去了微信开发文档怎么一直说需要https的请求(教学中没有说需要https,一直是http) 但是我的服务器只能使用http请求访问,如果硬是要 ...
- Simulink仿真入门到精通(五) Simulink模型的仿真
5.1 模型的配置仿真 由各种模块所构建的可视化逻辑连接,只是模型的外在表现,模型仿真的核心驱动器是被称作解算器(Solver)的组件,相当于Simulink仿真过程的心脏,驱动着模型仿真,它在每一个 ...
- 因为我说:volatile 是轻量级的 synchronized,面试官让我回去等通知!
因为我说:volatile 是轻量级的 synchronized,面试官让我回去等通知! volatile 是并发编程的重要组成部分,也是面试常被问到的问题之一.不要向小强那样,因为一句:volati ...
- dpdk中QSBR具体实现
目录 dpdk-QSBR实现 初始化 注册与注销 上线与下线 等待静默 附录 参考 dpdk-QSBR实现 dpdk19.01提供了qsbr模式的rcu库,其具体实现在lib/librte_rcu目录 ...
- MySQL笔记(6)-- SQL更新语句日志系统流程
一.背景 在上一篇[MySQL笔记(5)-- SQL执行流程,MySQL体系结构]中讲述了select查询语句在MySQL体系中的运行流程,从连接器开始,到分析器.优化器.执行器等,最后到达存储引擎. ...
- shell编程学习之使用jq对json数据进行提取
shell编程学习之使用jq对json提取 jq命令允许直接在命令行下对JSON进行操作,包括分片.过滤.转换等 ,jq是用C编写,没有运行时依赖,所以几乎可以运行在任何系统上.预编译的二进制文件可以 ...
- servlet本质是什么
作者:Javdroider Hong链接:https://www.zhihu.com/question/21416727/answer/339012081来源:知乎著作权归作者所有.商业转载请联系作者 ...
- python-pathlib
2019-12-12 04:27:17 我们知道在不同的操作系统中文件路径的组成方式是不同的,因此在python中关于路径的问题以往我们通常采用os.path.join来进行路径的字符串级别的串联,通 ...