【UVALive】3905 Meteor(扫描线)
题目
传送门:QWQ
分析
扫描线搞一搞。
按左端点排序,左端点相同时按右端点排序。
如果是左端点就$ cnt++ $,否则$ cnt-- $
统计一下$ Max $就行了
代码
#include <bits/stdc++.h>
using namespace std;
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);
}
}
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);
}
}events[maxn*2];
int main(){
int T;scanf("%d",&T);
while(T--){
int w,h,n,e=0;
scanf("%d%d%d",&w,&h,&n);
for(int i=0;i<n;i++){
int x,y,a,b;
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){
events[e++]=(Event){L,0};
events[e++]=(Event){R,1};
}
}
sort(events,events+e);
int cnt=0, ans=0;
for(int i=0;i<e;i++){
if(events[i].type==0) ans=max(ans,++cnt);
else --cnt;
}
printf("%d\n",ans);
}
return 0;
}