题目大意:给出一个矩形的照相机,左下角为(0,0),右上角为(w,h),现有n颗流星,给出了每颗流星的初始位置和速度,问这个照相机能拍摄最多的流星是多少颗,在矩形边上的不能算是拍到
解题思路:计算出每颗流星进入照相机框内的时间,这样就可以得到n条线段,线段如果有公共部分的话,就表示这几条线段所代表的流星能同时被拍摄到,这样的话,只要找出拥有公共部分最多的线段就可以得到答案了。这里要注意,如果再同一秒时,如果线段的左端点和另一条线段的右端点重叠的话,就表示一颗流星进入了,而另一颗流星超出了矩形的范围了,排序的时候要注意,因为这样代表的是两个结果的,应该是超出的排前面。
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 100010
int n, w, h;
struct Event{
double x;
int type;
bool operator < (const Event t) const {
return x < t.x || (x == t.x && type > t.type);
}
}e[maxn*2];
void count(int x, int w, int a, 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 test, x, y, a, b;
scanf("%d", &test);
while(test--) {
int cnt = 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;
count(x,w,a,L,R);
count(y,h,b,L,R);
if(R > L) {
e[cnt++] = (Event){L,0};
e[cnt++] = (Event){R,1};
}
}
sort(e,e+cnt);
int count = 0, ans = 0;
for(int i = 0; i < cnt; i++) {
if(e[i].type == 0)
ans = max(ans,++count);
else
--count;
}
printf("%d\n",ans);
}
return 0;
}