poj 2566 Bound Found (前缀和,尺取法(two pointer))
题意 :给定一个长度为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)];
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
26using namespace std;
27#define For(i, n) for (int i=0;i<int(n);++i)
28typedef long long LL;
29typedef double DB;
30const int N=1E5+7;
31const int inf = 0x3f3f3f3f;
32int a[N];
33int n ,k;
34struct Q
35{
36 int id;
37 int sum;
38}pre[N];
39
40bool 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
47void 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
80int 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}