poj2566 尺取法

Posted xiaobuxie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2566 尺取法相关的知识,希望对你有一定的参考价值。

传送门:https://vjudge.net/problem/POJ-2566

题意 :给出一个整数列,有正数和负数,求一段子串之和的绝对值最接近所给出的t。并输出该段子序列之和及左右端点。

听了胡老师的建议,最近都是以挑战程序设计竞赛为主线。这题也是从那里过来的。其实尺取法就是双指针,但是要注意单调性,就是扫一遍的事情了。

这题其实也是一道水题,只是最近好像不在状态,WA了几次sb错误。

首先说说思路吧,题目给子串,自然而然想到处理前缀和使得O(1)查询子串和。然后按值从小到大排个序,接下来就转换成在前缀和这个数列里面,找两个端点,使得他们的差最接近t。这样就转换成尺取法的常规做法了。双指针,当差比t小时,++r,反之++l。注意边界。

然后用了个pair来搞id。

犯二的点:把anssum初始化为1e9+100,人家t也可以去到1e9的好吧。。。然后sum【0】初始化在循环外。。。。。然后对sum数组排序没有把sum[0]考虑进来。。。。感觉最近状态真的太差了。。

技术图片
 1 // Cease to struggle and you cease to live
 2 #include <iostream>
 3 #include <cmath>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <vector>
 9 #include <set>
10 #include <map>
11 #include <stack>
12 using namespace std;
13 typedef long long ll;
14 pair<ll,int> sum[100000+8];
15 ll abss(ll a){return a>=0?a:-a;}
16 int n;
17 ll k;
18 #define L min(sum[ansl].second,sum[ansr].second)+1
19 #define R max(sum[ansl].second,sum[ansr].second)
20 void solve(ll q){
21     int l=0,r=1,ansl=0,ansr=1;
22     ll anss=abss(sum[r].first-sum[l].first);
23     while(1){
24         ll d=abss(sum[r].first-sum[l].first);
25         if(abss(d-q)<abss(anss-q)){
26             anss=d;
27             ansl=l;
28             ansr=r;
29         }
30         if(d==q){
31             printf("%lld %d %d\n",q,L,R);
32             //cerr<<"a"<<l<<‘ ‘<<r<<endl;
33             return;
34         }
35         if(l==n-1 && r==n) break;
36         if(l==r-1) ++r;
37         else if(d>q || r==n) ++l;
38         else ++r;
39     }
40     printf("%lld %d %d\n",anss,L,R);
41 }
42 int main() {
43     while(~scanf("%d%lld",&n,&k)){
44         if(n==0 && k==0 ) break;
45         sum[0]=make_pair((ll)0,0);
46         for(int i=1;i<=n;++i){
47             ll t;
48             scanf("%lld",&t);
49             sum[i]=make_pair(sum[i-1].first+t,i);
50         }
51         sort(sum,sum+1+n);
52         for(int i=1;i<=k;++i){
53             ll q;
54             scanf("%lld",&q);
55             solve(q);
56         }
57     }
58     return 0;
59 }
View Code

 

以上是关于poj2566 尺取法的主要内容,如果未能解决你的问题,请参考以下文章

poj2566 尺取法

POJ2566-Bound Found (尺取法)

poj 2566 尺取法

Bound Found [POJ2566] [尺取法]

POJ - 2566 Bound Found(尺取法+前缀和)

尺取法好题POJ2566-Bound Found