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 ...
随机推荐
- js 面向对象中,定义一个函数的过程
定义一个函数做的两件事:1: 实例化一个Function对象:2: 实例化一个Object对象,并给该函数扩展prototype属性指向这个构造函数 大致过程如图所示: 每一种引用类型(函数,对象,数 ...
- swoft 上传图片到 阿里云oss aliyun-oss
1.swoft 获取上传的文件 .官方文档上面没有看到 $files = $request->getUploadedFiles(); $file = $files['file']; 2.在模型 ...
- win下安装virtualenv和创建django项目
一.由于一直在Linux环境下开发,想了解一下winPython开发环境: 1.打开cmd,pip install virtualenv 2.virtualenv test 由于这样需要进入到目录下才 ...
- C++类的多态
目录 一.静态多态 二.动态多态 三.虚函数 四.纯虚函数 五.C++ 接口(抽象类) 六.应用经验 七.版权声明 多态按字面的意思就是多种形态.当类之间存在层次结构,并且类之间是通过继承关联时,就可 ...
- ggplot之多变量绘图
1. 普通plot 准备数据. x<-seq(0,2*pi,0.05) y<-sin(x) z<-cos(x) data<-data.frame(x,y,z) plot: pl ...
- Scrapy 入门教程
Scrapy 是用 Python 实现的一个为了爬取网站数据.提取结构性数据而编写的应用框架. Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 通常我们可以很简单的通过 ...
- .NET 开发工具盘点和现状
在这里我盘点一下.NET的开发工具:Visual Studio.Jetbrains Rider.Mono Develop.SharpDevelop.QuickSharp.Visual Studio C ...
- Journal of Proteome Research | Proteomic analysis of Rhizobium favelukesii LPU83 in response to acid stress.(酸胁迫下根瘤菌LPU83(Rhizobium favelukesii)的蛋白质组学分析)(解读人:丑天胜)
文献名:Proteomic analysis of Rhizobium favelukesii LPU83 in response to acid stress.(酸胁迫下根瘤菌LPU83(Rhizo ...
- Javascript的document对象
对象属性 document.title //设置文档标题等价于HTML的<title>标签 document.bgColor / ...
- 批量redis未授权检测工具&批量redis弱口令爆破工具
今天需要然后就百度搜索了一波,然后自己稍微改了一下: #!/usr/bin/python3 # -*- coding: utf-8 -*- """ @Author: 偷来 ...