zoukankan      html  css  js  c++  java
  • USACO 1.3 Milking Cows

    简化题意:求至少有一条线段覆盖的最大区间和没有线段覆盖的最大区间(注意题目是左闭右开区间(好像左开右闭也可以?))

    第一反应:线段树(wu)

    这道题做法好像很多的样子啊。

    虽然以这道题“渺小”的数据范围来说,不需要特别优秀的解法。

    法一

    比较直观的一个方法。

    对所有的线段按照左端点从小到大进行排序。

    扫一遍,把所有重叠的线段合并起来。

    再扫一遍,统计两种答案。

    法二

    算是上面的那个方法的变形吧。

    对所有的线段按照左端点从小到大进行排序。

    设置两个变量$s$,$t$,表示当前可以被连续覆盖的区间的起点和终点。

    如果能够接得上,即$f[i].l<=t$,那么更新右端点:$t=max(t,f[i].t)$

    如果接不上,就更新答案:

    有线段覆盖的区间$ans1=max(ans1,t-s)$

    没有线段覆盖的区间,就是当前这一条线段接不上的空隙:$ans2=max(ans2,f[i].l-t)$

    并且对当前可以被连续覆盖的区间进行更新:$s=f[i].l,t=f[i].r$

    注意我们更新答案是在不能继续接上的时候更新,但是最后一段可以被连续覆盖的区间没有这个“契机”去统计答案,所以要在循环结束的时候单独用最后一段$s$,$t$更新一遍答案。

     1 /*
     2 ID:Starry21
     3 LANG:C++
     4 TASK:milk2                 
     5 */
     6 #include<iostream>
     7 #include<string>
     8 #include<cstdio>
     9 #include<cstring>
    10 #include<map>
    11 #include<algorithm>
    12 using namespace std;
    13 #define N 5005
    14 int n;
    15 struct node{
    16     int l,r;
    17 }f[N];
    18 bool cmp(node p,node q)
    19 {
    20     return p.l<q.l;
    21 }
    22 int main() 
    23 {
    24     //freopen("milk2.in","r",stdin);
    25     //freopen("milk2.out","w",stdout);
    26     scanf("%d",&n);
    27     for(int i=1;i<=n;i++)
    28         scanf("%d %d",&f[i].l,&f[i].r);
    29     sort(f+1,f+n+1,cmp);
    30     int s=f[1].l,t=f[1].r,ans1=0,ans2=0;
    31     for(int i=2;i<=n;i++)
    32     {
    33         if(f[i].l<=t) t=max(t,f[i].r);
    34         else
    35         {
    36             ans1=max(ans1,t-s);
    37             ans2=max(ans2,f[i].l-t);
    38             s=f[i].l,t=f[i].r;
    39         }
    40     }
    41     ans1=max(ans1,t-s);
    42     printf("%d %d
    ",ans1,ans2);
    43     return 0;
    44 }
    Code

    法三

    受到树状数组的思想的影响,可以采用差分前缀和的方法。

    每条线段的起点$+1$,终点$-1$。

    前缀和大于$0$表示这个位置被覆盖了。

    (发现它躺在草稿箱里,不造为啥没发 可能是法三代码没贴上来?不管了

  • 相关阅读:
    Java学习的第二十八天
    Java学习的第二十七天
    第五章 作用域闭包
    第4章提升
    第3章函数作用域和块级作用域
    Vant中List列表下拉加载更多
    获取当前时间
    js比较两个时间的大小
    边框引起页面抖动
    计算两个数的百分比,保留两位小数
  • 原文地址:https://www.cnblogs.com/lyttt/p/11918992.html
Copyright © 2011-2022 走看看