LA 3905 Meteor
LA 3905
题意:有一个照相机相框,只有在相框内的点才可以被拍到,每一个点都有起始位置(x,y)和速度(a,b),问这个相框最多可以拍摄到多少个点
思路:拍摄肯定是一个瞬时性的动作,那么最终拍摄到点的多少肯定与时间的选取有关,因此可以吧所有的点在相框内出现的时间转化为一个区间。
最后进行遍历,遇到左区间加一,遇到右区间减一
如果a为正, 程序中的x/a代表经过x/a的时间长度才能遇到左端点,(w-x)/a代表还需要(w-x)/a的时间流星才能从相框中出去
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e5+10; struct node { double x; int type; bool operator < (const node & a) const { if(x!=a.x) return x<a.x; return type>a.type; //如果位置相同,肯定右区间在前,因为在相机边界上的点不会被照到 } }event[maxn*2]; 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)(w-x)/a); r=min(r,-(double)x/a); } } } int main() { int T; scanf("%d",&T); while(T--) { int n,w,h,x,y,a,b,e=0; scanf("%d%d%d",&w,&h,&n); for(int i=0;i<n;i++) { scanf("%d%d%d%d",&x,&y,&a,&b); double l=0,r=1e9; update(x,a,w,l,r); update(y,b,h,l,r); if(l<r) { event[e++]=(node) {l,0}; event[e++]=(node) {r,1}; } } sort(event,event+e); int ans=0; int cnt=0; for(int i=0;i<e;i++) { if(event[i].type==0) ans=max(ans,++cnt); else cnt--; } printf("%d\n",ans); } return 0; }
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e6; struct node { double l; int type; bool operator < (const node & a) const { if(l==a.l) return type>a.type; return l<a.l; } } eve[maxn]; void update(int x,int a,int w,double &l,double &r) { if(a==0) { if(x>=w||x<=0) r=l-1; } else { if(a>0) { l=max(l,-(x)*1.0/a); //进入相框当然要x,y坐标都进去才行 r=min(r,(w-x)*1.0/a); //出相框的话,只要x或者y其中之一离开相框就离开了 } if(a<0) { l=max(l,(x-w)*1.0/-a); r=min(r,x*1.0/-a); } } } int main() { int T; cin>>T; while(T--) { int n; int w,h; cin>>w>>h>>n; int e=0; for(int i=0; i<n; i++) { int x,y,a,b; cin>>x>>y>>a>>b; double l=0,r=1e9; update(x,a,w,l,r); update(y,b,h,l,r); if(l<r) { eve[e++]=node {l,0}; eve[e++]=node {r,1}; } } sort(eve,eve+e); int cur=0,ans=0; for(int i=0; i<e; i++) { if(eve[i].type==0) ans=max(ans,++cur); else cur--; } cout<<ans<<endl; } return 0; }