http://poj.org/problem?id=2566

Bound Found
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 2237   Accepted: 692   Special Judge

Description

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

Source

题意:找连续的串,求和绝对值与所给数字最接近的串。

思路:先求下标为1的到其他下的串的值,也就是前缀和;这样可以在O(1)的时间内求出各个串的和.比如S1(1,1),S3(1,3);

那么S3-S1就是S(2,3);

然后对上面所求的前缀和按从小到大排序。(因为取的是绝对值所以abs(Sn-Sk)==abs(Sk-Sn));

这样就可以用尺取法去做了。复杂度为O(n);

还可以用二分取找值,复杂度为O(n*log(n));

  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<math.h>
6 #include<vector>
7 #include<map>
8 #include<stack>
9 int cmp(const void*p,const void*q);
10 typedef struct pp
11 {
12 int cost ;
13 int x;
14 int y;
15 } ss;
16 const int N=1<<30;
17 const int M=1e6;
18 int a[M];
19 int b[M];
20 ss dp[M];
21 using namespace std;
22 int main(void)
23 {
24 int n,i,j,k,p,q;
25 while(scanf("%d %d",&p,&q),p!=0&&q!=0)
26 {
27 for(i=1; i<=p; i++)
28 {
29 scanf("%d",&a[i]);
30 }
31 dp[1].cost=a[1];
32 dp[1].x=1;
33 dp[1].y=1;
34 for(i=2; i<=p; i++)
35 {
36 dp[i].cost=a[i]+dp[i-1].cost;
37 dp[i].x=1;
38 dp[i].y=i;
39 }
40 qsort(dp+1,p,sizeof(ss),cmp);
41 while(q--)
42 {
43 scanf("%d",&k);
44 int ll=1;
45 int rr=1;
46 int minn=N;
47 int lb;
48 int rb;
49 int co;
50 for(i=1; i<=p; i++)
51 {
52 if(abs(abs(dp[i].cost)-k)<minn)
53 {
54 minn=abs(abs(dp[i].cost)-k);
55 lb=1;
56 rb=dp[i].y;
57 co=abs(abs(dp[i].cost));
58 }
59 }
60 while(rr<p)
61 {
62 while(rr<=p&&abs(dp[rr].cost-dp[ll].cost)<=k)
63 {
64 rr++;
65 }
66 if(rr==p+1)
67 {
68 rr--;
69 }
70 if(abs(dp[rr].cost-dp[ll].cost)>k&&rr-ll>1)
71 {
72 int nx=abs(abs(dp[rr].cost-dp[ll].cost)-k);
73 int ny=abs(abs(dp[rr-1].cost-dp[ll].cost)-k);
74 int kl=rr;
75 if(ny<nx)
76 {
77 kl--;
78 }
79 if(abs(abs(dp[kl].cost-dp[ll].cost)-k)<minn)
80 {
81 lb=min(dp[kl].y,dp[ll].y)+1;
82 rb=max(dp[kl].y,dp[ll].y);
83 minn=abs(abs(dp[kl].cost-dp[ll].cost)-k);
84 co=abs(dp[kl].cost-dp[ll].cost);
85 }
86 }
87 else if(abs(dp[rr].cost-dp[ll].cost)>k&&rr-ll==1)
88 {
89 if(abs(abs(dp[rr].cost-dp[ll].cost)-k)<minn)
90 {
91 lb=min(dp[rr].y,dp[ll].y)+1;
92 rb=max(dp[rr].y,dp[ll].y);
93 minn=abs(abs(dp[rr].cost-dp[ll].cost)-k);
94 co=abs(dp[rr].cost-dp[ll].cost);
95 }
96
97 }
98 else if(abs(dp[rr].cost-dp[ll].cost)<=k)
99 {
100 if(abs(abs(dp[rr].cost-dp[ll].cost)-k)<minn)
101 {
102 lb=min(dp[rr].y,dp[ll].y)+1;
103 rb=max(dp[rr].y,dp[ll].y);
104 minn=abs(abs(dp[rr].cost-dp[ll].cost)-k);
105 co=abs(dp[rr].cost-dp[ll].cost);
106 }
107
108 }
109 ll++;
110 }
111 printf("%d %d %d\n",co,lb,rb);
112 }
113 }
114 }
115 int cmp(const void*p,const void*q)
116 {
117 ss*ww=(ss*)p;
118 ss*w=(ss*)q;
119 if(ww->cost==w->cost)
120 {
121 return ww->y-w->y;
122 }
123 return ww->cost-w->cost;
124 }

二分

  1 #include<stdio.h>
2 #include<algorithm>
3 #include<stdlib.h>
4 #include<string.h>
5 #include<algorithm>
6 #include<iostream>
7 #include<map>
8 const int N=1000000;
9 int cmp(const void*p,const void*q);
10 int er(int n,int m,int t,int c);
11 typedef struct pp
12 {
13 int cost;
14 int le;
15 int ri;
16 } ss;//结构体记录前缀数组和和其左右端点
17 ss a[N];
18 int b[N],c[N];
19 int vv;
20 using namespace std;
21 int main(void)
22 {
23 int n,i,j,k,p,q;
24 while(scanf("%d %d",&p,&q),p!=0&&q!=0)
25 {
26 for(i=1; i<=p; i++)
27 scanf("%d",&b[i]);
28 int cnt=1;
29 a[cnt].cost=b[1];
30 a[cnt].le=1;
31 a[cnt].ri=1;
32 cnt++;
33 for(i=2; i<=p; i++)
34 {
35 a[cnt].cost=a[cnt-1].cost+b[i];
36 a[cnt].le=1;
37 a[cnt].ri=i;
38 cnt++;
39 }
40 qsort(a+1,cnt-1,sizeof(ss),cmp);
41 /*for(i=1;i<=p;i++)
42 {
43 printf("%d\n",a[i].cost);
44 printf("000\n");
45 printf("%d\n",a[i].ri);
46 }*/
47 for(i=1; i<=q; i++)
48 {
49 cin>>b[i];
50 }
51 for(int pq=1; pq<=q; pq++)
52 {
53 k=b[pq];
54 int minn=1<<30;
55 int ll=0;
56 int rr=0;
57 int uk=0;
58 for(j=1; j<=p; j++)
59 {
60 if(abs(abs(a[j].cost)-k)<minn)
61 {
62 minn=abs(abs(a[j].cost)-k);
63 uk=abs(a[j].cost);
64 ll=1;
65 rr=a[j].ri;
66 }
67 }//首先把所有前缀过一遍更新最小,因为二分时找不到
68 for(j=1; j<p; j++)
69 {
70 int kk=er(j+1,p,k,j);
71 vv=j;
72 if(kk==p)
73 {if(kk-vv>1)//这里需要判断下,kk-vv>1才能用下面的比较。
74 {int uu=abs(abs(a[kk-1].cost-a[j].cost)-k);
75 int w=abs(abs(a[kk].cost-a[j].cost)-k);
76 if(uu<w)
77 {
78 kk--;
79 }
80 int ww=abs(abs(a[kk].cost-a[j].cost)-k);
81 if(ww<minn)
82 {
83 minn=ww;
84 ll=min(a[kk].ri,a[j].ri)+1;
85 rr=max(a[kk].ri,a[j].ri);
86 uk=abs(a[kk].cost-a[j].cost);
87 }}
88 else if(kk-vv==1)//kk-vv正好为1时表明kk就为所找,不能再比较kk-1,因为kk-1为空值
89 { int ww=abs(abs(a[kk].cost-a[j].cost)-k);
90 if(ww<minn)
91 {
92 minn=ww;
93 ll=min(a[kk].ri,a[j].ri)+1;
94 rr=max(a[kk].ri,a[j].ri);
95 uk=abs(a[kk].cost-a[j].cost);
96 }
97 }
98 }
99 else
100 {
101
102 int uu=abs(abs(a[kk-1].cost-a[j].cost)-k);
103 int w=abs(abs(a[kk].cost-a[j].cost)-k);
104 if(uu<w)
105 {
106 kk--;
107 }
108 if(kk==j)
109 {
110 kk++;
111 }
112 int ww=abs(abs(a[kk].cost-a[j].cost)-k);
113 if(ww<minn)
114 {
115 minn=ww;
116 ll=min(a[kk].ri,a[j].ri)+1;
117 rr=max(a[kk].ri,a[j].ri);
118 uk=abs(a[kk].cost-a[j].cost);
119
120 }
121 }
122
123 }
124 printf("%d %d %d\n",uk,ll,rr);
125 }
126 }
127 }
128 int cmp(const void*p,const void*q)//二分查找
129 {
130 ss*w=(ss*)p;
131 ss*ww=(ss*)q;
132 return w->cost-ww->cost;
133 }
134 int er(int n,int m,int k,int c)
135 {
136 int y=(n+m)/2;
137 if(abs(a[y].cost-a[c].cost)==k)
138 {
139 return y;
140 }
141 else if(n==m)
142 {
143 return m;
144 }
145 else if(abs(a[y].cost-a[c].cost)>k&&abs(a[y-1].cost-a[c].cost)<k)
146 {
147 return y;
148 }
149 else if(abs(a[y].cost-a[c].cost)<k&&abs(a[y-1].cost-a[c].cost)<k)
150 {
151 return er(y+1,m,k,c);
152 }
153 else return er(n,y-1,k,c);
154 }

poj 2566Bound Found(前缀和,尺取法)的更多相关文章

  1. POJ 3061 Subsequence 二分或者尺取法

    http://poj.org/problem?id=3061 题目大意: 给定长度为n的整列整数a[0],a[1],--a[n-1],以及整数S,求出总和不小于S的连续子序列的长度的最小值. 思路: ...

  2. poj 2100 Graveyard Design(尺取法)

    Description King George has recently decided that he would like to have a new design for the royal g ...

  3. poj 2566 Bound Found(尺取法 好题)

    Description Signals of most probably extra-terrestrial origin have been received and digitalized by ...

  4. POJ 3061 (二分+前缀和or尺取法)

    题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点 ...

  5. POJ 2566 Bound Found(尺取法,前缀和)

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5207   Accepted: 1667   Spe ...

  6. 题解报告:poj 3061 Subsequence(前缀+二分or尺取法)

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  7. POJ_2566_Bound_Found_(尺取法+前缀和)

    描述 http://poj.org/problem?id=2566 给出一个整数序列,并给出非负整数t,求数列中连续区间和的绝对值最接近k的区间左右端点以及这个区间和的绝对值. Bound Found ...

  8. POJ 尺取法

    poj3061 Subsequence 题目链接: http://poj.org/problem?id=3061 挑战P146.题意:给定长度为n的数列整数a0,a1,...,a(n-1)以及整数S, ...

  9. POJ 3320 尺取法,Hash,map标记

    1.POJ 3320 2.链接:http://poj.org/problem?id=3320 3.总结:尺取法,Hash,map标记 看书复习,p页书,一页有一个知识点,连续看求最少多少页看完所有知识 ...

随机推荐

  1. CentOS6忘记root密码如何重置

    CentOS6忘记root密码,如何重置密码 ①     重启服务器,按"e"键进入修改系统开机项界面 ②    选择内核项,按"e"进入其中进行配置 在文件内 ...

  2. CAD简介

    Computer-aided design (CAD) is the use of computers (or workstations) to aid in the creation, modifi ...

  3. 【leetcode】1293 .Shortest Path in a Grid with Obstacles

    You are given an m x n integer matrix grid where each cell is either 0 (empty) or 1 (obstacle). You ...

  4. @Data 注解引出的 lombok

    今天在看代码的时候, 看到了这个注解, 之前都没有见过, 所以就查了下, 发现还是个不错的注解, 可以让代码更加简洁. 这个注解来自于 lombok,lombok 能够减少大量的模板代码,减少了在使用 ...

  5. Linux学习 - 文件特殊权限

    一.SUID权限(只针对文件) 只有可执行的二进制程序才能设定SUID权限 命令执行者要对该程序拥有x(执行)权限 1 拥有SUID的文件 /usr/bin/passwd 2 功能: 命令执行者(其他 ...

  6. Java操作csv文件

    以前就一直很想搞懂一个问题就是java如何读取和写入csv文件,现在要花时间总结一波. 主要使用的javaCSV.jar javaCSV API:http://javacsv.sourceforge. ...

  7. KVM配置

    安装依赖包(因最小化安装) [root@slave-master ~]# yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pc ...

  8. Dubbo中CompletableFuture异步调用

    使用Future实现异步调用,对于无需获取返回值的操作来说不存在问题,但消费者若需要获取到最终的异步执行结果,则会出现问题:消费者在使用Future的get()方法获取返回值时被阻塞.为了解决这个问题 ...

  9. ClassLoader.loadClass()与Class.forName()的区别《 转》

    ClassLoader.loadClass()与Class.forName()区别: ClassLoader.loadClass()与Class.forName()大家都知道是反射用来构造类的方法,但 ...

  10. 最基础的SSM框架整合篇

    一.简单理解 Spring.Spring MVC和MyBatis的整合主要原理就是将我们在单独使用Spring MVC和MyBatis过程中需要自己实例化的类都交由Ioc容器来管理,过程分为两步: 第 ...