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. jmeter+ant输出测试报告

    jmeter自己本身可以输出html测试报告的,不过这种自带的测试报告特别简陋,如下图所示,一般我们是不看这种的. 我们可以使用ant来输出更高效.更直观的测试报告. 首先下载安装ant, 我用的是a ...

  2. JavaScript | 新手村(一)变量,运算和变量方法

    资料来自:JavaScript 第一步 1. 向 html 页面添加 JavaScript 1.1 内部 JavaScript 在 html 文件中的 </body> 标签前插入代码: & ...

  3. 日常Java 2021/9/29

    StringBuffer方法 public StringBuffer append(String s) 将指定的字符串追加到此字符序列. public StringBuffer reverse() 将 ...

  4. Hbase与Phoenix整合

    目录 一.简介 二.安装 三.Phoenix Shell操作 SCHEMA操作 1.创建schema 2.使用schema 3.删除schema 表操作 1.显示所有表 2.创建表 3.表数据的增删改 ...

  5. ssh : connect to host XXX.XXX.XXX.XXX port : 22 connect refused

    初学者 写博客 如有不对之处请多多指教 我是要在俩个主机的俩个虚拟机上 用scp (security copy)进行文件远程复制. 但是 终端 提示 ssh : connect to host XXX ...

  6. 栈常考应用之括号匹(C++)

    思路在注释里.还是使用链栈的API,为啥使用链栈呢,因为喜欢链栈. //header.h #pragma once #include<iostream> using namespace s ...

  7. android studio 使用 aidl(二)异步回调

    基础使用请移步 android studio 使用 aidl (一) 首先建立在server端建立两个aidl文件 ITaskCallback.aidl 用于存放要回调client端的方法 // IT ...

  8. 【Java 基础】Java动态代理

    Java动态代理InvocationHandler和Proxy java动态代理机制中有两个重要的类和接口InvocationHandler(接口)和Proxy(类),这一个类Proxy和接口Invo ...

  9. Linux 性能优化笔记:应用监控

    指标监控 跟系统监控一样,在构建应用程序的监控系统之前,首先也需要确定,到底需要监控哪些指标.特别是要清楚,有哪些指标可以用来快速确认应用程序的性能问题. 对系统资源的监控,USE 法简单有效,却不代 ...

  10. 【C/C++】例题3-6 环状序列/算法竞赛入门经典/数组和字符串

    [字典序比较] 对于两个字符串,比较字典序,从第一个开始,如果有两位不一样的出现,那么哪个的ASCII码小,就是字典序较小.如果都一样,那么短的小. [题目] 输入一个环状串,输出最小的字典序序列. ...