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 ...
随机推荐
- python笔记26
一.今日内容 python中的方法 python中的方法+正则表达式的新内容 #分组 #分组命名 #引用分组 #爬虫的小例子 1.转义符 如:\n--->\\n--->print('\\n ...
- Yuchuan_Linux_C编程之九目录操作相关函数
一.整体大纲 二.相关函数 1. getcwd 函数作用:获取当前目录 头文件 #include <unistd.h> 函数原型 char *getcwd(char *buf, size_ ...
- 利用wps创建有目录的PDF/word
为什么要创建: 在阅读一些行业规范或者很长的文件,像是项目管理方案时,非常麻烦,定位需要重新返回目录去.--->所以我想能不能创建一个带目录的PDF,可以点击直接跳转,那就方便多了. 如何创建: ...
- SpringCloud第二代实战系列:一文搞定Nacos实现服务注册与发现
一.背景:SpringCloud 生态圈 在正式开始本篇文章之前我们先岔开来讲一下SpringCloud的生态圈. SpringCloud大家都比较熟悉了,它制定了分布式系统的标准规范,做了高度抽象和 ...
- nes 红白机模拟器 第4篇 linux 手柄驱动支持
小霸王学习机的真实手柄,实测CPU 占用 80% 接线图: 手柄读时序: joypad.c 驱动: 普通的字符设备驱动. #include <linux/module.h> #includ ...
- java中的对象 方法 引用 等一些抽象的概念是什么意思呢?
2020-03-14 最近这一段时间有点忙,好久都没有更新博客了,之后我会一直坚持下去的,和大家一同进步的. 这段时间一直在学java,相信刚开始学习java的小白,刚开始接触那么些抽象的概念一定和我 ...
- ES6中的Promise使用总结
One.什么是Promise? Promise是异步编程的解决方案,而它本身也就是一个构造函数,比传统的异步解决[回调函数]和[事件]更合理,更强大. Two.Promise有何作用? 作用:解决回调 ...
- golang Printf 函数有超过 10 个转义字符
verb 描述 %d 十进制整数 %x, %o, %b 十六进制.八进制.二进制整数 %f, %g, %e 浮点数:如 3.141593, 3.141592653589793, 3.141593e+0 ...
- Vue2.0 【第二季】第5节 Template制作模板
目录 Vue2.0 [第二季]第5节 Template制作模板 第5节 Template制作模板 一.直接写在选项里的模板 二.写在template标签里的模板 三.写在script标签里的模板 Vu ...
- Windows Server 2012 R2 域证书服务搭建
网管大叔说要给每个人颁发一个证书,这个证书很耗电 1.在服务器管理器中添加角色和功能 下一步 下一步 勾选Active Directory证书服务 下一步 下一步 勾选证书颁发机构,证书颁发机构Web ...