Bound Found (POJ - 2566,思维 + 尺取)
发布日期:2021-05-04 06:49:45 浏览次数:23 分类:技术文章

本文共 1396 字,大约阅读时间需要 4 分钟。

一.题目链接:

二.题目大意:

有 n 个数,编号为 a[1], a[2] ... a[n].

m 次询问,每次询问给出一个整数 t.

确定一个区间 [l, r],使得  ||\sum _{i=l}^{r} a[i]| - t| 最小.

并输出最小值即对应区间.

三.分析:

记序列 a 的前缀和为 sum,则问题转化为求区间 [l, r] 使得  ||sum[r] - sum[l]| - t| 取最小值.

我们可以对 sum 排序,同时记录 sum 的原始编号.

面对这样的问题求最小值,采用尺取法即可.

四.代码实现:

#include 
#include
using namespace std;typedef long long ll;const int M = (int)1e5;const int inf = 0x3f3f3f3f;pair
sum[M + 5];int main(){ int n, m, t; while(~scanf("%d %d", &n, &m) && (n + m)) { sum[0].first = sum[0].second = 0; for(int i = 1; i <= n; ++i) { scanf("%d", &t); sum[i].first = sum[i - 1].first + t; sum[i].second = i; } sort(sum, sum + n + 1); while((m--) > 0) { scanf("%d", &t); int l = 0, r = 1; int ans, ansl, ansr, d, dans = inf; while(r <= n && dans) { int d = sum[r].first - sum[l].first; if((int)abs(d - t) < dans) { ans = d; dans = (int)abs(d - t); ansl = sum[l].second; ansr = sum[r].second; } if(d > t) ++l; else ++r; if(l == r) ++r; } if(ansl > ansr) swap(ansl, ansr); printf("%d %d %d\n", ans, ansl + 1, ansr); } } return 0;}

 

上一篇:阶乘分解 (算法竞赛进阶指南 P136,质因数分解)
下一篇:Weak Pair (HDU - 5877 ,DFS + 离散化 + 权值线段树)

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2025年03月15日 17时29分26秒