POJ 2566 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个数的序列,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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值