LA3905

题目大意:
给你一个矩形照相机和n个流星的初始位置和速度,求能找到流星最多的时刻,边界上的点不算入内。

思路:
线性扫描 + 事件点处理
可以以时间为轴,计算每个流星出现的时间然后化成平行于x轴的线段,用一根竖线进行扫描,扫描到最多的时刻记录下来每次更新。

代码:

#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <algorithm>
const int maxn = 100010;

struct event {
    double x;
    int type;
    bool operator < (const event &a) const {
        return x < a.x || (x == a.x && type > a.type) ;
    }
}e[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,w,h,a,b;
    scanf("%d",&T);
    while(T--) {
        int n,x,y;
        int num = 0;
        scanf("%d %d",&w,&h);
        scanf("%d",&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(R > L) {
                e[num++] = (event){L,0};
                e[num++] = (event){R,1};
            }
        }
        sort(e,e+num);
        int cnt = 0, ans = 0;
        for(int i = 0; i < num; i++) {
            if(e[i].type == 0) ans = max(ans,++cnt);
            else cnt--;
        }
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(LA3905)