UVALive - 3905 Meteor 统计

题目大意:给出一个矩形的照相机,左下角为(0,0),右上角为(w,h),现有n颗流星,给出了每颗流星的初始位置和速度,问这个照相机能拍摄最多的流星是多少颗,在矩形边上的不能算是拍到

解题思路:计算出每颗流星进入照相机框内的时间,这样就可以得到n条线段,线段如果有公共部分的话,就表示这几条线段所代表的流星能同时被拍摄到,这样的话,只要找出拥有公共部分最多的线段就可以得到答案了。这里要注意,如果再同一秒时,如果线段的左端点和另一条线段的右端点重叠的话,就表示一颗流星进入了,而另一颗流星超出了矩形的范围了,排序的时候要注意,因为这样代表的是两个结果的,应该是超出的排前面。

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 100010
int n, w, h;
struct Event{
	double x;
	int type;
	bool operator < (const Event t) const {
		return x < t.x || (x == t.x && type > t.type);
	}
}e[maxn*2];

void count(int x, int w, int a, 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 test, x, y, a, b;
	scanf("%d", &test);
	while(test--) {
		int cnt = 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;
			count(x,w,a,L,R);
			count(y,h,b,L,R);
			if(R > L) {
				e[cnt++] = (Event){L,0};
				e[cnt++] = (Event){R,1};
			}
		}
		sort(e,e+cnt);
		int count = 0, ans = 0;
		for(int i = 0; i < cnt; i++) {
			if(e[i].type == 0)
				ans = max(ans,++count);
			else
				--count;	
		}
		printf("%d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值