Bound Found POJ
来源:互联网 发布:东莞网站关键字优化 编辑:程序博客网 时间:2024/06/14 13:57
Bound Found
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
先来简单说一下题目的意思, 给你一个长度 为 n 的 序列 ,然后 给
你 一个 t 值,让你 求的 一个 连续的 子序列,使得 该序列的 和 的
绝对值,最为接近 t 值,然后 输出 满足 条件的 序列的 和 的绝对值 ,
和 该序列的 左右 边界 下标 。题目的意思很简单,而且 这道题就
是 根据 尺取法 的 思想来写的 , 以前 的 尺取法 的类型题 中 while、循环中的 判断条件 往往是一个 定值 ,而这道题中的 是一个 不断 改变的值 ,每一次 更新为 最优解 ,从而充当 判断条件,
这个 题 我用了一个 pair《int, int》sum[], 这个 数组 是用来 存储 前 I 个 数的 和 ,和 对应的 下标 i ;【思路】
……前缀和比较神奇的想法。一般来说,我们必须要保证数列单调性,才能使用尺取法。
预处理出前i个数的前缀和,和编号i一起放入pair中,然而根据前缀和大小进行排序(从小到大排序(sort 函数的 默认排序方式))。由于abs(sum[i]-sum[j])=abs(sum[j]-sum[i]),可以忽视数列前缀和的前后关系。此时,sum[r]-sum[l]有单调性。
因此我们可以先比较当前sum[r]-sum[l]与t的差,并更新答案。
如果当前sum[r]-sum[l]
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef pair<int, int> p;p sum[100010];int main(){ int n, m, num; while(scanf("%d%d", &n, &m) && n+m) { sum[0] = make_pair(0, 0);// 读入 一组数据也可以 用 sum[0] = p(0, 0); for(int i = 1; i <= n; i++)// 先用 pair 存起来 { scanf("%d", &num); sum[i] = make_pair(sum[i-1].first + num, i); } sort(sum, sum+1+n);// 从小到大 排序 这里 要注意 排序的 范围 是 sum -> sum+1+n 不要 写成 sum+1->sum+1+n 如果你要是 写成 后者的话,那么 sum[0].first <= sum[1].first 就不一定成立啦 因为 sum[1].first 可能 是 负值, 那么 在下面 尺取法 的 方法中 temp 可能会小于零 啦 这样程序就会出错啦; int t; int L, R, s, e, temp, dif, ans; while(m--) { scanf("%d", &t); s = 0;// 这里 之所以 s = 0, e = 1;是为了 防止 s = e 出现 空区间 e = 1; dif = INT_MAX; while(e <= n) { temp = sum[e].first - sum[s].first; if(abs(temp-t) < dif) { dif = abs(temp - t); L = sum[s].second; R = sum[e].second; ans = temp; } if(temp < t) e++;// temp 还可能 变大一点 else if(temp > t) s++;// temp 还可能 变小一点 else break;// s = e 最优解 直接跳出循环 if(s == e) e++;// 防止出现空区间 } if(L > R) swap(L, R);// 由于 排序的 原因 L R 是 乱序 负值的 printf("%d %d %d\n", ans, L+1, R); } } return 0;}
- POJ 2566 Bound Found
- POJ-2566-Bound Found
- poj 2566Bound Found
- poj 2566 Bound Found
- poj 2566 Bound Found
- poj 2566 Bound Found
- POJ 2566 Bound Found
- 【POJ】2566 Bound Found
- POJ 2566 Bound Found
- poj 2566 Bound Found
- Bound Found POJ
- Bound Found POJ
- POJ 2566 Bound Found
- poj 2566 Bound Found (尺取法)
- poj 2566 Bound Found(尺取法)
- POJ 2566 Bound Found(尺取)
- poj 2566 Bound Found(尺取法)
- [POJ 2566] Bound Found (TwoPointer入门)
- 转行学Java有可能成为高薪大牛吗?
- 《剑指Offer》做题总结(三)
- python opencv去图片水印
- WebService 四种发布方式总结
- Hadoop源码解读-Job初始化过程
- Bound Found POJ
- (八)监听耳机插入拔出状态
- 线性链表:单链
- java绘制图片并打印功能
- 基本概念
- iframe 父子传值
- HTML浮动窗口与多媒体效果、表单与页面控件
- 矩阵的之字型遍历-LintCode
- 华硕飞行堡垒触摸板快捷键失效