Bound Found [POJ2566] [尺取法]

Posted ibilllee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bound Found [POJ2566] [尺取法]相关的知识,希望对你有一定的参考价值。

题意

给出一个整数列,求一段子序列之和最接近所给出的t。输出该段子序列之和及左右端点。

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

分析

这道题可以看得出来是要用尺取法,尺取法的关键是要找到单调性。而序列时正时负,显然是不满足单调性的。

如果记录下前缀和,并排好序,这样就满足单调性了,就可以使用前缀和了

代码

技术分享图片
 1 #include<set>
 2 #include<map>
 3 #include<queue>
 4 #include<stack>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 #include<iostream>
 9 #include<algorithm>
10 #define RG register int
11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
13 #define ll long long
14 #define inf (1<<30)
15 #define maxn 100005
16 using namespace std;
17 int n,k;
18 int num[maxn];
19 struct P{
20     int id,s;
21     inline int operator < (const P &a)const{
22         return s==a.s?id<a.id:s<a.s;
23     }
24 }p[maxn];
25 inline int read()
26 {
27     int x=0,f=1;char c=getchar();
28     while(c<0||c>9){if(c==-)f=-1;c=getchar();}
29     while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
30     return x*f;
31 }
32 
33 void solve()
34 {
35     int aim=read();
36     int l=0,r=1,mn=inf,al,ar,ans;
37     while(l<=n&&r<=n&&mn)
38     {
39         int cal=p[r].s-p[l].s;
40         if(abs(cal-aim)<mn)
41         {
42             mn=abs(cal-aim);
43             al=p[r].id,ar=p[l].id,ans=cal;
44         }
45         if(cal>aim)            ++l;
46         else if(cal<aim)    ++r;
47         else    break;
48         if(l==r)    ++r;
49     }
50     if(al>ar)    swap(al,ar);
51     printf("%d %d %d
",ans,al+1,ar);
52 }
53 
54 int main()
55 {
56     while(1)
57     {
58         n=read(),k=read();
59         if(!n&&!k)    return 0;
60         rep(i,1,n)    num[i]=read();
61         p[0]=(P){0,0};
62         rep(i,1,n)    p[i].s=p[i-1].s+num[i],p[i].id=i;
63         sort(p,p+1+n);
64         rep(i,1,k)    solve();
65     }
66     return 0;
67 }
View Code

以上是关于Bound Found [POJ2566] [尺取法]的主要内容,如果未能解决你的问题,请参考以下文章

poj 2566 Bound Found 尺取法

POJ - 2566 Bound Found(尺取法+前缀和)

poj 2566 Bound Found

Bound Found [POJ2566] [尺取法]

Greedy:Bound Found(POJ 2566)

POJ 2566:Bound Found(Two pointers)