码迷,mamicode.com
首页 > 其他好文 > 详细

Bound Found [POJ2566] [尺取法]

时间:2018-07-12 18:14:43      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:upper   font   follow   cstring   左右   target   分享图片   ase   HERE   

题意

给出一个整数列,求一段子序列之和最接近所给出的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\n",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] [尺取法]

标签:upper   font   follow   cstring   左右   target   分享图片   ase   HERE   

原文地址:https://www.cnblogs.com/ibilllee/p/9300321.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!