zoukankan      html  css  js  c++  java
  • LA3905流星

    题意:
          在一个二维平面上有n个流星,每个流星有自己的初始位置和速度,有一个照相机,张相机的可视范围是一个矩形框,左下角(0,0)右上角(w ,h),然后问你相机的矩形内出现的最多的流星数是多少? 


    思路:
          感觉是一道很不错的题目,想到流星数目,第一反应就是可以把他转化成时间段,我们求出每个流星的进入相机时间,和出相机时间,这样就会得到一个时间段,流星的最大
    数量也就是时间段的最大重叠部分,这个不解释了应该不难理解,现在问题就来了,我们怎么求得所有的时间段呢?一开始我也感觉很麻烦,然后在白书上学了一个比较方便的方法,我们求时间段可以先把流星分解了,x,y单独算,进入的时间肯定是进x进y的最大值,出去的时间肯定是出x,出y的最小值,这样我们分别求完之后就ok了,如果L>=R就证明没有在相机范围内出现过,下面给出求L,R的代码
    void Update(int x ,int a ,int w ,double& L ,double& R)
    {
       if(a == 0)
       {
           if(x <= 0 || x >= w) R = L - 1; //永远也进步了相机
       }
       else if(a > 0)//往上跑 
       {
          L = Max(L ,-(double)x / a);
          R = Min(R ,(double)(w - x) / a);
       }
       else//往下跑
       {
          L = Max(L ,(double)(w - x) / a);//理解不了的注意这里的a是负的
          R = Min(R ,-(double)x / a); 
       }
               
    }


    求x,y的时候都是用的上面的那个,只不过传的参数不一样罢了,具体细节可以看代码。
      这样我们就得到了所有流星的时间段L,R(L>=R的是不满足的,直接丢弃),然后就是求区间的最大重叠面积了,这个也比较好求,如果你不嫌麻烦可以写线段树贪心去求,时间复杂度是O(n*log(n))的,不过有一个更省事更快的方法,就是扫面线法O(n)<其实这么说有漏洞,因为扫描线涉及到排序,排序是O(n*log(n))的,这个地方大家知道就行了>,我们可以把所有端点都扔进结构体数组里,然后按照时间从小到大排序,如果时间相等那么就后端点在前面(这样的原因是题目中说在相机边框上的不算,如果算的话就入端点在前面),排序之后直接扫一遍,遇到前端点就++,后端点就--,过程中最大的值就是答案,这个应该很好理解,不理解的在纸上画一画,每次变化的时候都是在端点上变化的,这个就是经典的扫描线想法,扫描线也可以配合着线段树应用,求重叠面积,体积,周长啥的。这个题目还有一个小小的优化(白书上说的),我们可以躲开浮点运算,因为整个程序里涉及到的除法就是除以速度,速度的范围是绝对值<=10,那么我们直接把被除数扩大1,2,3..10的最小公倍数2520倍就行了,这样保证都是整除,至于为什么我想不用我解释了。






    #include<stdio.h>
    #include<string.h>
    #include<algorithm>


    #define N 100000 + 10


    using namespace std;




    typedef struct
    {
        int mk;
        double time;
    }NODE;


    NODE node[N+N];


    bool camp(NODE a ,NODE b)
    {
         return a.time < b.time || a.time == b.time && a.mk < b.mk;
    }


    double Max(double x ,double y)
    {
        return x > y ? x : y;
    }


    double Min(double x ,double y)
    {
        return x < y ? x : y;
    }


    void Update(int x ,int a ,int w ,double& L ,double& R)
    {
       if(a == 0)
       {
           if(x <= 0 || x >= w) R = L - 1;
       }
       else if(a > 0) 
       {
          L = Max(L ,-(double)x / a);
          R = Min(R ,(double)(w - x) / a);
       }
       else
       {
          L = Max(L ,(double)(w - x) / a);
          R = Min(R ,-(double)x / a); 
       }
               
    }


    int main ()
    {
        int t ,w ,h ,n ,i;
        int x ,y ,a ,b;
        scanf("%d" ,&t);
        while(t--)
        {
           scanf("%d %d" ,&w ,&h);
           scanf("%d" ,&n);
           int nowid = 0;
           for(i = 1 ;i <= n ;i ++)
           {
              scanf("%d %d %d %d" ,&x ,&y ,&a ,&b);
              double L = 0 ,R = 999999999;
              Update(x ,a ,w ,L ,R);
              Update(y ,b ,h ,L ,R);
              if(L < R)
              {
                 node[++nowid].time = L;
                 node[nowid].mk = 1;
                 node[++nowid].time = R;
                 node[nowid].mk = -1;
              }
           }
           int Ans = 0;
           sort(node + 1 ,node + nowid + 1 ,camp);
           int sum = 0;
           for(i = 1 ;i <= nowid ;i ++)
           {
              sum += node[i].mk;
              if(Ans < sum) Ans = sum;
           }
           printf("%d " ,Ans);
        }
        return 0;  
    }
       




    //排除浮点型运算
    void Update(int x ,int a ,int w ,int& L ,int& R)
    {
       if(a == 0)
       {
           if(x <= 0 || x >= w) R = L - 1;
       }
       else if(a > 0) 
       {
          L = Max(L ,-x * 2520 / a);
          R = Min(R ,(w - x) * 2520 / a);
       }
       else
       {
          L = Max(L ,(w - x) * 2520/ a);
          R = Min(R ,-x * 2520/ a); 
       }
               
    }





  • 相关阅读:
    5917
    安装wdcp后,反向代理全过程
    今天 想了个问题,阿里旺旺及时消息
    5917全部电影 我反代了一个站
    曾经4000多IP的站,被百度K了
    asp.net 出现Operation is not valid due to the current state of the object.
    自然语言处理 |文本相似度计算与文本匹配问题
    Node.js v16.13.0 连接MySQL数据库8.0.27失败问题
    NLP自然语言处理 | Prolog 语言入门教程:
    NLP自然语言处理 | TFIDF与余弦相似性的应用(二):找出相似文章
  • 原文地址:https://www.cnblogs.com/csnd/p/12062639.html
Copyright © 2011-2022 走看看