• 【尺取法好题】POJ2566-Bound Found


    【题目大意】

    给出一个整数列,求一段子序列之和最接近所给出的t。输出该段子序列之和及左右端点。

    【思路】

    ……前缀和比较神奇的想法。一般来说,我们必须要保证数列单调性,才能使用尺取法。

    预处理出前i个数的前缀和,和编号i一起放入pair中,然而根据前缀和大小进行排序。由于abs(sum[i]-sum[j])=abs(sum[j]-sum[i]),可以忽视数列前缀和的前后关系。此时,sum[r]-sum[l]有单调性。

    因此我们可以先比较当前sum[r]-sum[l]与t的差,并更新答案。

    如果当前sum[r]-sum[l]<t,说明和还可以更大,r++。

    同理,如果sum[r]-sum[l]>t,说明和还可以更小,l++。

    如果sum[r]-sum[l]=t,必定是最小答案。

    【注意点】

    由于序列不能为空,即l<>r,如果l=r则r++。

    我们更新答案的时候左右区间端点为乱序,输出的时候调整一下。

    就OK了!

    *本来想要尺取弄一个合集,然而这道题做的时候想了半天。还是单独拿出来吧orz

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const int MAXN=1e5+5;
     8 const int INF=2147483640;
     9 pair<int,int> sum[MAXN];
    10 int n,k,t;
    11 
    12 void init()
    13 {
    14     sum[0]=make_pair(0,0);
    15     int tmp=0;
    16     for (int i=1;i<=n;i++) 
    17     {
    18         int x;
    19         scanf("%d",&x);
    20         tmp+=x;
    21         sum[i]=make_pair(tmp,i);
    22     }
    23     sort(sum,sum+n+1);     
    24 }
    25 
    26 void solve()
    27 {
    28     scanf("%d",&t);
    29     int l=0,r=1,minans=INF,ans,ansl,ansr;
    30     while (r<=n && minans)//这里一开始写成了ans,以后变量名不要取那么相像orz 
    31     {
    32         int delta=sum[r].first-sum[l].first;
    33         if (abs(delta-t)<=minans)
    34         {
    35             minans=abs(delta-t);
    36             ans=delta;
    37             ansl=sum[l].second;
    38             ansr=sum[r].second;
    39         }
    40         if (delta<t) r++; 
    41         if (delta>t) l++;
    42         if (l==r) r++;//☆注意序列不能为空!
    43     }
    44     if (ansl>ansr) swap(ansl,ansr);//注意排序后是无序的,左右区间要调整回有序 
    45     printf("%d %d %d
    ",ans,ansl+1,ansr); 
    46 }
    47 
    48 int main()
    49 {
    50     while (scanf("%d%d",&n,&k)!=EOF) 
    51     {
    52         init();
    53         for (int i=1;i<=k;i++) solve();
    54     }
    55     return 0;
    56 } 
  • 相关阅读:
    Tree
    a letter and a number
    A problem is easy
    connect设置超时的方法
    C++客户端访问Java服务端发布的SOAP模式的WebService接口
    gSoap的“error LNK2001: 无法解析的外部符号 _namespaces”解决方法
    先序序列和后序序列并不能唯一确定二叉树
    二叉树的非递归遍历
    web service,soap ,http,tcp,udp
    byte[]数组和int之间的转换
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5962512.html
Copyright © 2020-2023  润新知