POJ 2566 Bound Found(尺取法,前缀和)
Time Limit: 5000MS | Memory Limit: 65536K | |||
Total Submissions: 5207 | Accepted: 1667 | Special Judge |
Description
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
Output
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和k,输入n个数和k个t,求一个连续子序列使得这个连续子序列的和最接近t,输出这个子序列的和和它的左右端点
解题思路:尺取法.要使用尺取法必须要保证数列的单调性,而这道题输入的n个数并不是单调的,然后借鉴了大佬的博客...这里用到了前缀和,预处理出前i个数的前缀和,和编号i一起放入pair中,然后根据前缀和从小到大排序,此时sum[r]-sum[l]就有了单调性。可以通过比较sum[r]-sum[l]与t的关系不断进行更新,如果sum[r]-sum[l]<t,说明和可以更大,所以r++;如果sum[r]-sum[l]>t,说明和可以更小,所以l++;如果sum[r]-sum[l]=t,必定是最小答案。由于序列不能为空,所以当l=r时,r++。更新答案的时候左右区间端点为乱序,输出的时候交换一下即可
因为前缀和不单调,所以需要先排序。在原数组开头添加0,求出前缀数组。题目即转化为在前缀数组中找pre[i],pre[j],两者之差最接近t,。对于每次找到的2个下标分别为i和j的2个数,所对应a的区间为[min(i, j) + 1, max(i, j)]。
那么前缀数组排序后,尺取法便可以求得最接近t的值。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
struct Node
{
int id, tot;
};
Node a[maxn];
int n, q, ans, ansl, ansr;
int cmp(Node a, Node b)
{
if (a.tot == b.tot) return a.id<b.id;
else return a.tot<b.tot;
}
int main()
{
while (scanf("%d%d", &n, &q) != EOF && (n + q))
{
a[].id = , a[].tot = ;
for (int i = ; i <= n; i++)
{
int x;
scanf("%d", &x);
a[i].id = i;
a[i].tot = a[i - ].tot + x;
}
sort(a, a + n + , cmp);
for (int i = ; i<q; i++)
{
int t;
scanf("%d", &t);
int l = , r = , minx = INF;
while (l <= r && r <= n)
{
int tmp = a[r].tot - a[l].tot;
if (abs(tmp - t)<minx)
{
minx = abs(tmp - t);
ans = tmp;
ansl = a[l].id;
ansr = a[r].id;
}
if (tmp<t) r++;
else if (tmp>t) l++;
else break;
if (l == r) r++;
}
if (ansl>ansr) swap(ansl, ansr);
printf("%d %d %d\n", ans, ansl + , ansr);
}
}
return ;
}
POJ 2566 Bound Found(尺取法,前缀和)的更多相关文章
- poj 2566 Bound Found 尺取法 变形
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 2277 Accepted: 703 Spec ...
- poj 2566"Bound Found"(尺取法)
传送门 参考资料: [1]:http://www.voidcn.com/article/p-huucvank-dv.html 题意: 题意就是找一个连续的子区间,使它的和的绝对值最接近target. ...
- poj 2566 Bound Found 尺取法
一.首先介绍一下什么叫尺取 过程大致分为四步: 1.初始化左右端点,即先找到一个满足条件的序列. 2.在满足条件的基础上不断扩大右端点. 3.如果第二步无法满足条件则到第四步,否则更新结果. 4.扩大 ...
- POJ 2566 Bound Found 尺取 难度:1
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1651 Accepted: 544 Spec ...
- poj 2566 Bound Found(尺取法 好题)
Description Signals of most probably extra-terrestrial origin have been received and digitalized by ...
- POJ_2566_Bound_Found_(尺取法+前缀和)
描述 http://poj.org/problem?id=2566 给出一个整数序列,并给出非负整数t,求数列中连续区间和的绝对值最接近k的区间左右端点以及这个区间和的绝对值. Bound Found ...
- poj 3061(二分 or 尺取法)
传送门:Problem 3061 https://www.cnblogs.com/violet-acmer/p/9793209.html 马上就要去上课了,先献上二分AC代码,其余的有空再补 题意: ...
- POJ 3061 Subsequence ( 二分 || 尺取法 )
题意 : 找出给定序列长度最小的子序列,子序列的和要求满足大于或者等于 S,如果存在则输出最小长度.否则输出 0(序列的元素都是大于 0 小于10000) 分析 : 有关子序列和的问题,都可以考虑采用 ...
- POJ 3061 Subsequence ( 尺取法)
题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...
随机推荐
- iOS使用Instruments的工具
使用Instruments的工具 iOSXcodeInstrumentsInstruments是一个官方提供的强大的性能调试工具集. 1.Blank(空模板):创建一个空的模板,可以从Library库 ...
- C++面向对象高级编程(三)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...
- vs 2013远程调试
1. 找到本机Remote Debugger/x64文件夹,将其拷贝到远程机器上 2.运行x64文件夹下的msvsmon.exe,将其设置为“无身份验证模式”,记住端口号,一会儿要用到 3.在vs中打 ...
- Mysql双机热备--预备知识
1.双机热备 对于双机热备这一概念,我搜索了很多资料,最后,还是按照大多数资料所讲分成广义与狭义两种意义来说. 从广义上讲,就是对于重要的服务,使用两台服务器,互相备份,共同执行同一服务.当一台服务器 ...
- Servlet自动加载
--初始化数据库连接 在<servlet>标签下 <servlet-name>ServletDemo</servlet-name> <servlet-clas ...
- java之接口
背景 为了防止[多重继承]:(在面向对象的编程语言(例如java)中,指一个类可以同时继承多个父类的行为和特征功能)所引发的"致命方块",出现了接口. 使用 定义 public ...
- 框架重构:测试中的DateTime.Now
存在的问题 DateTime.Now是C#语言中获取计算机的当前时间的代码: 但是,在对使用了DateTime.Now的方法进行测试时,由于计算机时间的实时性,期望值一直在变化.如:计算年龄. pub ...
- 滑动ViewPager引起swiperefreshlayout刷新的冲突
ViewPager是Android中提供的页面切换的控件,SwipeRefreshLayout是Android提供的下拉刷新控件,通过SwipeRefreshLayout可以很简单的实现下拉刷新的功能 ...
- 日志组件logback的介绍及配置使用方法(一)
一.logback的介绍 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classic和logback-acc ...
- BZOJ4399 魔法少女LJJ【线段树合并】【并查集】
Description 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了 LJJ感叹道"这里真是个迷人的绿色世界,空气清新.淡雅 ...