题目链接如下: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4144
题目大意:给一个长方形右上角坐标(w,h),左下角坐标(0,0)。再给出N个运动的点,点i的初始位置为(xi,yi),速度向量为(ai,bi)。可知点的运动轨迹为(xi+ai*t,yi+bi*t)。求这些点中同时处于这个长方形范围内的点的最大个数。
思想:扫描,维护信息,避免重新计算。
(1) 算出每个点出现在长方形范围中的时间段区间。
(2) 将这些区间看做静止的。用一个竖直线去从做到右扫描。
(3)移动到区间的左端点,说明进入一个新区间,cnt++;移动到区间的右端点,离开区间,cnt--;
(4)扫描的过程中维护cnt最大的值。既是解答
import java.util.*;
class Event implements java.lang.Comparable{
int x;
int type;
Event(int x,int type)
{
this.x=x;
this.type=type;
}
@Override
public int compareTo(Object arg0) {
Event temp=(Event)arg0;
if(this.x<temp.x||(this.x==temp.x&&this.type>temp.type))
return -1;
else if(this.x==temp.x&&this.type==temp.type)
return 0;
else
return 1;
}
}
public class Main {
static int max(int a1,int a2)
{
return a1>=a2?a1:a2;
}
static int min(int a1,int a2)
{
return a1<a2?a1:a2;
}
private static void update(int xi,int ai,int w,int[]LR)
{
if(ai==0)
{
if(xi<=0||xi>=w)
LR[LR.length-1]=LR[0]-1;
}
else if(ai>0)
{
LR[0]=max(LR[0],-2520*xi/ai);
LR[LR.length-1]=min(LR[LR.length-1],2520*(w-xi)/ai);
}
else
{
LR[0]=max(LR[0],2520*(w-xi)/ai);
LR[LR.length-1]=min(LR[LR.length-1],-2520*xi/ai);
}
}
static Event[] events=new Event[200010];
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
int t=in.nextInt();
int xi,yi,ai,bi;
while((t--)!=0)
{
int w=in.nextInt();
int h=in.nextInt();
int n=in.nextInt();
int e=0;
for(int i=0;i<n;i++)
{
int[] LR=new int[2];
LR[0]=0;
LR[1]=Integer.MAX_VALUE;
xi=in.nextInt();yi=in.nextInt();
ai=in.nextInt();bi=in.nextInt();
update(xi,ai,w,LR);
update(yi,bi,h,LR);
if(LR[1]>LR[0]){
events[e++]=new Event(LR[0],0);
events[e++]=new Event(LR[1],1);
}
}
Arrays.sort(events,0,e);
int cnt=0,ans=0;
for(int i=0;i<e;i++)
{
if(events[i].type==0)
ans=max(ans,++cnt);
else
cnt--;
}
System.out.println(ans);
}
}
}