题目大意:
给你一个矩形照相机和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;
}