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. CSP 画图(201512-3)

    问题描述 用 ASCII 字符来画图是一件有趣的事情,并形成了一门被称为 ASCII Art 的艺术.例如,下图是用 ASCII 字符画出来的 CSPRO 字样. ..____.____..____. ...

  2. python线程中的同步问题

    多线程开发可能遇到的问题 假设两个线程t1和t2都要对num=0进行增1运算,t1和t2都各对num修改1000000次,num的最终的结果应该为2000000.但是由于是多线程访问,有可能出现下面情 ...

  3. Django基础之视图(views)层、模板层

    目录 Django基础之视图(views)层.模板层 JsonResponse 向前端返回一个json格式字符串的两种方式 重写Django中的json的某个方法 form表单上传文件 FBV与CBV ...

  4. Dasha and Photos CodeForces - 761F (前缀优化)

    大意: 给定n*m初始字符矩阵, 有k个新矩阵, 第$i$个矩阵是由初始矩阵区间赋值得到的, 求选择一个新矩阵, 使得其余新矩阵到它距离和最小. 字符集比较小, 可以考虑每次区间覆盖对每个字符的贡献. ...

  5. js文件的框架

    Ext.define("BeidaSoft.SFJCGL.rcjwgl.bdgl.BdglGrid", { extend : "BeidaSoft.XTGL.base.Q ...

  6. private修饰的方法可以通过反射访问,那么private的意义是什么?

    反射代码: package test; public class Person { private String userName= "Tom"; private void pla ...

  7. c++MMMMM:oo

    1.union,struct和class的区别

  8. CentOS7搭建FastDFS V5.11分布式文件系统(三)

    1.测试 前面两篇博文已对FastDFS的安装和配置,做了比较详细的讲解.FastDFS的基础模块都搭好了,现在开始测试下载. 1.1 配置客户端 同样的,需要修改客户端的配置文件: /etc/fdf ...

  9. Chrome OS 更新新版本可让Linux访问USB连接的Android设备

    谷歌再次为Chrome OS带来了重大版本更新,使版本号达到了75.本次更新的一大亮点就是允许在Chrome OS上运行的Linux能够识别通过USB方式连接的Android设备,能够让用户使用Lin ...

  10. web开发规范文档二

    头部        header\hd 内容块      content\con\bd text txt title 尾部        footer 导航        nav\menu sub-n ...