题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=460&problem=4144&mosmsg=Submission+received+with+ID+12204651
题目大意:给定那个流星的初始位置,和向量速度v(1,2),表示每秒x轴移动一个单位,y轴移动两个单位。给定相机拍摄的范围,求相机在什么时刻拍摄的流星最多,边界上的不算,相机的左下起始点为(0,0)右上点的范围由输入给定。
题目解析:分析可知,流星的运动轨迹对我们所求的结果没有意义,我们只需求出每颗流星进入相机拍摄范围的时间段,得到n个区间段,要求某个时刻拍摄的流星最多,既求所有流星时间段重合最多。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1000010
typedef struct node
{
double x;
int type;
}node;
node map[MAX];
int w,h,n;
double max(double x,double y)
{
return x>y?x:y;
}
double min(double x,double y)
{
return x<y?x:y;
}
int cmp(const void *aa,const void *bb)
{
node *a=(node *)aa;
node *b=(node *)bb;
if (a->x!=b->x)
return a->x < b->x ? -1:1;
return b->type-a->type;
}
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)(x-w)/a);
R=min(R,-(double)x/a);
}
return ;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int i,j,cnt=0,ans=0,sum=0;
int x,y,a,b;
scanf("%d%d",&w,&h);
scanf("%d",&n);
for (i=0;i<n;i++)
{
double L=0.0,R=1e9;
scanf("%d%d%d%d",&x,&y,&a,&b);
update(x,a,w,L,R);
update(y,b,h,L,R);
if (R>L)
{
map[cnt++]=(node){L,0};
map[cnt++]=(node){R,1};
}
}
qsort(map,cnt,sizeof(node),cmp);
for (i=0;i<cnt;i++)
{
if (map[i].type==0)
{
sum++;
if (ans<sum)
ans=sum;
}
else
{
sum--;
}
}
printf("%d\n",ans);
}
return 0;
}