poj 2566 Bound Found (前缀和,尺取法(two pointer))
Bound Found
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 |
题意 :给定一个长度为n的区间.然后给k次询问,每次一个数t,求一个区间[l,r]使得这个区间和的绝对值最接近t
没办法直接尺取.
先预处理出来前缀和
如果要找一对区间的和的绝对值最最近t
等价于找到两个数i和j,使得sum[i]-sum[j]的绝对值最接近t,且i<>j
那么对前缀和排序...然后尺取
因为答案要输出下标
所以之前先存一下下标.
然后对于i,j
所对应的区间为[min(pre[i].id,pre[j].id)+1,max(pre[i],id,pre[j].id)];
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************************* 2 > File Name: code/poj/2566.cpp 3 > Author: 111qqz 4 > Email: rkz2013@126.com 5 > Created Time: 2015年09月24日 星期四 22时10分08秒 6 ************************************************************************/ 7 8 #include<iostream> 9 #include<iomanip> 10 #include<cstdio> 11 #include<algorithm> 12 #include<cmath> 13 #include<cstring> 14 #include<string> 15 #include<map> 16 #include<set> 17 #include<queue> 18 #include<vector> 19 #include<stack> 20 #include<cctype> 21 #define y1 hust111qqz 22 #define yn hez111qqz 23 #define j1 cute111qqz 24 #define ms(a,x) memset(a,x,sizeof(a)) 25 #define lr dying111qqz 26 using namespace std; 27 #define For(i, n) for (int i=0;i<int(n);++i) 28 typedef long long LL; 29 typedef double DB; 30 const int N=1E5+7; 31 const int inf = 0x3f3f3f3f; 32 int a[N]; 33 int n ,k; 34 struct Q 35 { 36 int id; 37 int sum; 38 }pre[N]; 39 40 bool cmp(Q a,Q b) 41 { 42 if (a.sum<b.sum) return true; 43 if (a.sum==b.sum&&a.id<b.id) return true; 44 return false; 45 } 46 47 void solve ( int t) 48 { 49 int ansl,ansr,ans; 50 int l = 0 ; 51 int r = 1; 52 int mi = inf; 53 while ( r<= n ) 54 { 55 int tmp = pre[r].sum - pre[l].sum; 56 57 if (abs(tmp-t)<mi) 58 { 59 mi = abs(tmp-t); 60 ansl = min(pre[l].id,pre[r].id)+1; 61 ansr = max(pre[l].id,pre[r].id); 62 ans = tmp; 63 } 64 if (tmp<t) 65 { 66 r++; 67 } 68 else 69 if (tmp>t) 70 { 71 l++; 72 } 73 else break; 74 75 if (l==r) r++; 76 } 77 printf("%d %d %d\n",ans,ansl,ansr); 78 } 79 80 int main() 81 { 82 #ifndef ONLINE_JUDGE 83 freopen("in.txt","r",stdin); 84 #endif 85 while (scanf("%d %d",&n,&k)!=EOF) 86 { 87 if (n==0&&k==0) break; 88 pre[0].id = 0 ; 89 pre[0].sum = 0 ; 90 for ( int i = 1 ; i <= n ; i++) 91 { 92 scanf("%d",&a[i]); 93 pre[i].sum = pre[i-1].sum + a[i]; 94 pre[i].id = i ; 95 // cout<<pre[i].sum<<" "; 96 } 97 // cout<<endl; 98 99 sort(pre,pre+n+1,cmp); 100 // for ( int i = 0 ; i <= n ; i++) cout<<pre[i].sum<<" "; cout<<endl; 101 for ( int i = 1 ; i <= k ; i++) 102 { 103 int x; 104 scanf("%d",&x); 105 solve(x); 106 } 107 } 108 109 #ifndef ONLINE_JUDGE 110 fclose(stdin); 111 #endif 112 return 0; 113 }