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个数的序列,k组询问,每组询问给你一个数m,让你求这个序列的子序列之和的绝对值中与m最相近的序列,输出这个序列在原序列中的左端点的位置和右端点的位置
思路:
这个题的思路用的是尺取,如果想用尺取的话,得符合一定的规律(比如递增,递减之类的),所以你得对序列进行排序,按照它们的前缀和从小到大排序,同时记录序号,然后再用正常的尺取就行了
pair可以用结构体实现,但是学一个新东西也挺好的,而且也不难,可以增长你的知识面,所以不会pair的可以先去学习一下
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
using namespace std;
pair<int,int>v[100005];
int n,k,m;
const int inf=0x3f3f3f3f;
void solve()
{
int l=0,r=1,minn=inf,id1=0,id2=1,ans;
while(r<=n)
{
int x=v[l].first,y=v[r].first;
int sum=y-x;//y一定是大于等于x的,所以sum是大于等于0的
if(abs(y-x-m)<minn)
{
id1=min(v[l].second,v[r].second);
id2=max(v[l].second,v[r].second);
ans=y-x;
minn=abs(y-x-m);
}
if(sum<m)r++;
else if(sum>m)l++;
else break;
if(l==r)r++;
}
printf("%d %d %d\n",ans,id1+1,id2);
}
int main()
{
while(scanf("%d%d",&n,&k)&&(n||k))
{
v[0]=make_pair(0,0);
int sum=0,x;
for(int a=1;a<=n;a++)
{
scanf("%d",&x);
sum+=x;
v[a].first=sum;
v[a].second=a;
}
sort(v,v+1+n);
while(k--)
{
scanf("%d",&m);
solve();
}
}
return 0;
}