这题题意:给你一个矩形框,n个点的坐标和方向向量,问你最多可能在框中出现多少个点。
首先,把每个点在框中的起始时间和终止时间求出来,然后利用扫描法,离散出每个点的起始和终止时间,由于边界不算,所以注意下顺序问题。
这题有很多地方值得学习:
1.问题简化,每次直接求横坐标和纵坐标,分别取最大和最小值,这里计算的时候没有注意a的正负而错了一发。
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 100005
#define INF 1e9
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,s,t) for(int i=s;i<=t;i++)
#define ull unsigned long long
#define ll long long
using namespace std;
int w,h,n;
struct E
{
double t;
int tpye;
bool operator < (const E a) const
{
if(t==a.t) return tpye>a.tpye;
else return t<a.t;
}
}e[maxn*2];
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)(x-w)/a);//这里a是负数,所以要乘-1
R=min(R,-(double)x/a);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&w,&h);
scanf("%d",&n);
int id=0;
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=INF;
updata(x,a,w,L,R);
updata(y,b,h,L,R);
if(L<R)
{
e[id++]=(E){L,0};//注意这种写法
e[id++]=(E){R,1};
}
}
sort(e,e+id);
int cnt=0,ans=0;
for(int i=0;i<id;i++)
{
if(e[i].tpye==0)
cnt++;
else
cnt--;
ans=max(ans,cnt);
}
printf("%d\n",ans);
}
return 0;
}