#include<bits/stdc++.h>
#define debu
using namespace std;
typedef double DB;
struct point
{
int flag;
DB w;
point(DB a=0.0,int b=0):w(a),flag(b) {}
};
int n;
DB w,h;
vector<point> all;
void make(DB px,DB py,DB vx,DB vy)
{
if(vx==0)
if(px<=0||px>=w) return ;
if(vy==0)
if(py<=0||py>=h) return ;
DB tmpl1=min(-px/vx,(w-px)/vx);
DB tmpl2=max(-px/vx,(w-px)/vx);
DB tmpr1=min(-py/vy,(h-py)/vy);
DB tmpr2=max(-py/vy,(h-py)/vy);
DB l=max(tmpl1,tmpr1);
DB r=min(tmpl2,tmpr2);
// cout<<l<<" "<<r<<endl;
if(l>r) return ;
all.push_back(point(l,0));
all.push_back(point(r,1));
}
int cmp(point a,point b)
{
if(a.w==b.w) return a.flag>b.flag;
else return a.w<b.w;
}
void solve()
{
int ans=0,tmp=0;
sort(all.begin(),all.end(),cmp);
/*for(int i=0;i<all.size();i++)
cout<<all[i].w<<" "<<all[i].flag<<endl;*/
for(int i=0; i<all.size(); i++)
{
if(all[i].flag==0)
{
tmp++;
ans=max(ans,tmp);
}
else tmp--;
}
printf("%d\n",ans);
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
int t;
scanf("%d",&t);
while(t--)
{
all.clear();
scanf("%lf%lf",&w,&h);
scanf("%d",&n);
for(int i=0; i<n; i++)
{
DB px,py,vx,vy;
scanf("%lf%lf%lf%lf",&px,&py,&vx,&vy);
// cout<<px<<" "<<py<<" "<<vx<<" "<<vy<<endl;
make(px,py,vx,vy);
}
solve();
// cout<<"************************"<<endl;
}
return 0;
}
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1906
题解:求出各个流星到达区域内的时间范围(l,r),则问题转化为求一个数t,使得t被包含在最多的区间。所以每次遇到一个左端点,ans++并更新;否则若为右端点ans--。注意有左端点与右端点相等时先处理右端点(将所有端点记录,flag==1代表右端点,flag==0代表左端点,全部加入vector排序时flag作为第二关键字即可)。注意vx或vy等于0时的情况。