LA 3905 流星(扫描法)

题目:https://vjudge.net/problem/UVALive-3905

把进入的流星看成一个个时间的事件,当扫描线和最多的开区间相交时,维护答案。

应注意细节,事件的左端和事件的右端重合时,应先处理事件右端。

#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
const int maxn=100000+10;
struct Event{
	double x;
	int type;
	bool operator <(const Event &a)const{
	return x<a.x ||(x==a.x && type>a.type);
	}
}events[2*maxn];
int w,h,n;

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--){
		scanf("%d %d %d",&w,&h,&n);
		int e=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=1e9;
			update(x,a,w,l,r);
			update(y,b,h,l,r);
			if(r>l){
				events[e++]=Event{l,0};
				events[e++]=Event{r,1};
			}
		}
		sort(events,events+e);
		int cnt=0,ans=0;
		for(int i=0;i<e;i++){
			if(events[i].type==0) ans=max(ans,++cnt);
			else cnt--;
		}
		printf("%d\n",ans);
	}
	
}

 

发布了57 篇原创文章 · 获赞 58 · 访问量 617

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/103923553