LA 3905 Meteor

LA 3905

题意:有一个照相机相框,只有在相框内的点才可以被拍到,每一个点都有起始位置(x,y)和速度(a,b),问这个相框最多可以拍摄到多少个点

思路:拍摄肯定是一个瞬时性的动作,那么最终拍摄到点的多少肯定与时间的选取有关,因此可以吧所有的点在相框内出现的时间转化为一个区间。

最后进行遍历,遇到左区间加一,遇到右区间减一

如果a为正, 程序中的x/a代表经过x/a的时间长度才能遇到左端点,(w-x)/a代表还需要(w-x)/a的时间流星才能从相框中出去

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn=1e5+10;
struct node
{
    double x;
    int type;
    bool operator < (const node & a) const
    {
        if(x!=a.x)
            return x<a.x;
        return  type>a.type;           //如果位置相同,肯定右区间在前,因为在相机边界上的点不会被照到
    }
}event[maxn*2];

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;
    scanf("%d",&T);
    while(T--)
    {
     int n,w,h,x,y,a,b,e=0;
     scanf("%d%d%d",&w,&h,&n);
     for(int i=0;i<n;i++)
     {
         scanf("%d%d%d%d",&x,&y,&a,&b);
         double l=0,r=1e9;
         update(x,a,w,l,r);
         update(y,b,h,l,r);
         if(l<r)
         {
             event[e++]=(node) {l,0};
             event[e++]=(node) {r,1};
         }
     }
         sort(event,event+e);
         int ans=0;
         int cnt=0;
         for(int i=0;i<e;i++)
         {
             if(event[i].type==0) ans=max(ans,++cnt);
             else                 cnt--;
         }
         printf("%d
",ans);
     }
    return 0;
}
View Code
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn=1e6;
struct node
{
    double l;
    int type;
    bool operator < (const node & a) const
    {
        if(l==a.l) return type>a.type;
        return l<a.l;
    }
} eve[maxn];

void update(int x,int a,int w,double &l,double &r)
{
    if(a==0)
    {
        if(x>=w||x<=0) r=l-1;
    }
    else
    {
        if(a>0)
        {
            l=max(l,-(x)*1.0/a);     //进入相框当然要x,y坐标都进去才行
            r=min(r,(w-x)*1.0/a);     //出相框的话,只要x或者y其中之一离开相框就离开了
        }
        if(a<0)
        {
            l=max(l,(x-w)*1.0/-a);
            r=min(r,x*1.0/-a);
        }
    }
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        int w,h;
        cin>>w>>h>>n;
        int e=0;
        for(int i=0; i<n; i++)
        {
            int x,y,a,b;
            cin>>x>>y>>a>>b;
            double l=0,r=1e9;
            update(x,a,w,l,r);
            update(y,b,h,l,r);
            if(l<r)
            {
                eve[e++]=node {l,0};
                eve[e++]=node {r,1};
            }
        }
        sort(eve,eve+e);
        int cur=0,ans=0;
        for(int i=0; i<e; i++)
        {
            if(eve[i].type==0) ans=max(ans,++cur);
            else               cur--;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code