UVALive - 3905 Meteor 统计

来源:互联网 发布:隐形眼镜护理液 知乎 编辑:程序博客网 时间:2024/05/21 14:48

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

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

#include<algorithm>#include<cstdio>#include<cstring>using namespace std;#define maxn 100010int 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;}


0 0
原创粉丝点击