这题很明显是扫描线,把流星在相框里的时间的区间整理出来,然后扫描以下线就可以了。
//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/10/1.
// Mail:1016427040@qq.com or jasonshaosjj@gmail.com
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+100;
struct eg{
double t;
int type;
bool operator < (const eg &rhs) const {
return t<rhs.t||(t==rhs.t&&type>rhs.type);
}
}edge[maxn*2];
//0<x+at<w||0<y+at<h
void updata(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;
scanf("%d",&t);
while(t--)
{
int w,h,n,e=0;
scanf("%d%d%d",&w,&h,&n);
int x,y,a,b;
for(int i=0;i<n;i++){
scanf("%d%d%d%d",&x,&y,&a,&b);
double L=0,R=1e9;
updata(x,a,w,L,R);
updata(y,b,h,L,R);
if(L<R){
edge[e++]=(eg){L,0};
edge[e++]=(eg){R,1};
}
}
sort(edge,edge+e);
int cnt=0,ans=0;
for(int i=0;i<e;i++){
if(edge[i].type==0) {cnt++;ans=max(ans,cnt);}
else cnt--;
}
printf("%d\n",ans);
}
return 0;
}
还可以把L,R改为整形,然后更新的时候*2520。
因为2520是1~10的公倍数,所以除了之后必定是个整数,所以一定是个整数区间。
//0<x+at<w||0<y+at<h
void updata(int x,int a,int w,int &L,int &R)
{
if(a==0){
if(x<=0||x>=w) R=L-1;
}
else if(a>0){
L=max(L,-x*2520/a);
R=min(R,(w-x)*2520/a);
}
else{
L=max(L,(w-x)*2520/a);
R=min(R,-x*2520/a);
}
}