Bound Found
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 2277   Accepted: 703   Special Judge

Description

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

Source

题意:给你n个数字,这些数字可正可负,再给你个数字t,求在这个数列中一个连续的子序列,和的绝对值与t相差最小
 
错因分析:刚开始看到这道题目觉得很变态,尺取法怎么可能做得出来,这些数字是可正可负的,,后来看了题解,才恍然大悟,正因为是可正可负所以不能直接用尺取法去解题(尺取法必须是找到单调性),需要进行转化,找到单调性,但是a[i]数组是不能改变的,因为要求连续,那么就自然想到对a[i]求前缀和
 
先贴上别人好的代码,核心思想:对sum进行从小到大的排序,注意需要加入<0,0>这点(为了求得单独的sum,就是从第一个节点到sum[i]对应的i节点),然后尺取法设置左右两个端点,直接在sum数组上进行尺取法,需要注意的是对两个端点移动的判断,假设得出的int temp=p[r].first - p[l].first<k,说明temp偏小,那么r端点右移,否则>k的话,说明temp偏大,需要l端点右移,但是需要注意不能出现l==r的情况,因为序列不能为空,l==r,则序列为空;还有一点很重要的是因为求得是和的绝对值,即|sum[j]-sum[i]|,那么只需要对sum数组进行从小到大排序,用大的减去小的就可以了(这也是去绝对值的体现)
#include<cstdio>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include<map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
pair<int, int > p[100005];
int n, m, k;
void solve(int k)
{
int l = 0, r = 1, al, ar, av, minn = inf;
while (l<=n&&r<=n&&minn!=0)
{
int temp=p[r].first - p[l].first;
if (abs(temp - k) < minn)
{
minn = abs(temp - k);
ar = p[r].second;
al = p[l].second;
av = temp;
}
if (temp> k)
l++;
else if (temp < k)
r++;
else
break;
if (r == l)
r++;
}
if(al>ar)
swap(al,ar);//因为al和ar大小没有必然关系()取绝对值,所以//要交换
printf("%d %d %d\n", av, al+1, ar);
}
int main()
{
while (~scanf("%d %d", &n, &m))
{
if (!n&&!m) return 0;
p[0] = make_pair(0, 0);
for (int i = 1; i <= n; i++)
{
scanf("%d", &p[i].first);
p[i].first += p[i - 1].first;
p[i].second = i;
}
sort(p, p + n + 1);
while (m--)
{
scanf("%d", &k);
solve(k);
}
}
return 0;
}

  下面是自己的wa代码

好好找茬

#include<cstdio>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include<map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
pair<int, int > p[100005];
int n, m, k;
void solve(int k)
{
int l = 0, r = 1, al, ar, av, minn = inf;
while (l<=n&&r<=n)
{
int temp = p[r].first - p[l].first;
if (abs(temp - k) < minn)
{
minn = abs(temp - k);
ar = p[r].second;
al = p[l].second;
av = temp;
}
if (temp > k)
l++;
else if (temp < k)
r++;
else
break;
if (r == l)
r++;
}
printf("%d %d %d\n", av, al+1, ar);
}
int main()
{
while (~scanf("%d %d", &n, &m))
{
if (!n&&!m) return 0;
p[0] = make_pair(0, 0);
for (int i = 1; i <= n; i++)
{
scanf("%d", &p[i].first);
p[i].first += p[i - 1].first;
p[i].second = i;
}
sort(p + 1, p + n + 1);
while (m--)
{
scanf("%d", &k);
solve(k);
}
}
return 0;
}

  

poj 2566 Bound Found 尺取法 变形的更多相关文章

  1. POJ 2566 Bound Found(尺取法,前缀和)

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5207   Accepted: 1667   Spe ...

  2. poj 2566"Bound Found"(尺取法)

    传送门 参考资料: [1]:http://www.voidcn.com/article/p-huucvank-dv.html 题意: 题意就是找一个连续的子区间,使它的和的绝对值最接近target. ...

  3. poj 2566 Bound Found 尺取法

    一.首先介绍一下什么叫尺取 过程大致分为四步: 1.初始化左右端点,即先找到一个满足条件的序列. 2.在满足条件的基础上不断扩大右端点. 3.如果第二步无法满足条件则到第四步,否则更新结果. 4.扩大 ...

  4. POJ 2566 Bound Found 尺取 难度:1

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 1651   Accepted: 544   Spec ...

  5. poj 2566 Bound Found(尺取法 好题)

    Description Signals of most probably extra-terrestrial origin have been received and digitalized by ...

  6. POJ:2566-Bound Found(尺取变形好题)

    Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5408 Accepted: 1735 Special J ...

  7. poj 3061(二分 or 尺取法)

    传送门:Problem 3061 https://www.cnblogs.com/violet-acmer/p/9793209.html 马上就要去上课了,先献上二分AC代码,其余的有空再补 题意: ...

  8. POJ 3061 Subsequence ( 尺取法)

    题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...

  9. poj 3320 复习一下尺取法

    尺取法(two point)的思想不难,简单来说就是以下三步: 1.对r point在满足题意的情况下不断向右延伸 2.对l point前移一步 3.  回到1 two point 对连续区间的问题求 ...

随机推荐

  1. [转帖]英特尔的 ME 或侵犯 Minix3 的自由软件许可证

    英特尔的 ME 或侵犯 Minix3 的自由软件许可证 [日期:2017-12-11] 来源:Linux公社  作者:非非然 [字体:大 中 小] https://www.linuxidc.com/L ...

  2. 如何在java中去除中文文本的停用词

    1.  整体思路 第一步:先将中文文本进行分词,这里使用的HanLP-汉语言处理包进行中文文本分词. 第二步:使用停用词表,去除分好的词中的停用词. 2.  中文文本分词环境配置 使用的HanLP-汉 ...

  3. Ubuntu关机等待时间解决方案

    关于GDM问题(a stop job is running for session c1 of user root 1 min 30 s) 注意了,这个不是系统的问题,是配置的问题.鼓捣了老久才找出来 ...

  4. 面试35-删除字符串重复字符-删除出现在第二个字符串中的字符-第一个只出现一次的字符-hash表计数

    #include<iostream>#include<algorithm>#include<functional>using namespace std;char ...

  5. composer命令介绍之install和update及其区别

    composer 是 php 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们. 然而,对于如何『安装他们』,新手可能并不清楚.网上的答案有的说 composer in ...

  6. spark教程(一)-集群搭建

    spark 简介 建议先阅读我的博客 大数据基础架构 spark 一个通用的计算引擎,专门为大规模数据处理而设计,与 mapreduce 类似,不同的是,mapreduce 把中间结果 写入 hdfs ...

  7. Codeforces 1201E2. Knightmare (hard)

    传送门 看到棋盘先黑白染色冷静一下 然后分析发现,如果初始时两只马在同色的格子,那么一定是后手吃先手 反之一定是先手吃后手 所以分类讨论一下,如果初始在同色的格子,并且后手到达终点的步数更少,那么后手 ...

  8. CF1151F Sonya and Informatics

    cf luogu 我们最终要的序列一定是前面全是0,后面全是1,假设总共\(m\)个0,那么这等价于前\(m\)位0的个数为\(m\).当然一开始可能数量没有\(m\) 那就把前\(m\)位0的数量作 ...

  9. 01 初识HTML

    HTML是什么? 超文本标记语言(Hypertext Markup Language, HTML)是一种用于创建网页的标记语言. 本质上是浏览器可识别的规则,我们按照规则写网页,浏览器根据规则渲染我们 ...

  10. Echarts常见问题汇总

    关于echarts使用的常见问题总结  来源:李文杨 关于echarts使用的问题总结1.legend图例不显示的问题:在legend中的data为一个数组项,数组项通常为一个字符串,每一项需要对应一 ...