LA - 3905 ——Meteor 流星

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16454

1.对于每一颗流星而言,真正有意义的是它穿越矩形的有效时间,所以其实我们需要得到所有流星的有效时间

2.这样的话,原问题就转化更加具体的:某个时刻最多同时穿过多少个时间段?

解决方案:

  将每一个时间区间,转化为两个事件:开始事件和结束事件。我们对所有事件按照时间排序,然后我们有一个初始化为0的tot变量计数,接着遍历这个序列,遇到开始事件就+1,遇到结束时间就-1,然后在遍历的过程中保存最大的tot,这个最大值就是最后的解。

  最后要注意开始时间与结束事件重叠的情况,即当某个时刻开始时间与结束事件重叠。如果是先+后-的话,那么最大值会是2,相反就会使1。显然,在这里,后者才是正确的,因为由题意所有时间区间结尾开区间。

#include <cstdio>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;

struct P {
    double t;
    int type;
    P(double t=0, int type=0) {
        this->t = t;
        this->type = type;
    }
    bool operator<(const P& p) const {
        if(t == p.t)    return type > p.type; // 时间一样时,优先结束事件
        return t < p.t;
    }
} p[200005]; 

int tot;
double l, r;

// 得到某颗流星在某一维度上面经过矩形范围的区间,如果 左边界>右边界 说明 区间不存在
void f(int x, int w, int a)
{
    if(a == 0) {
        if(x <= 0 || x >= w) {
            l = INF;
            r = 0;
        }
    } else if(a > 0){
        l = max(l, -1.0*x/a);
        r = min(r, 1.0*(w-x)/a);
    } else {
        l = max(l, 1.0*(w-x)/a);
        r = min(r, -1.0*x/a);
    }
}

int main ()
{
    int T, w, h, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d%d", &w, &h, &n);
        int x, y, a, b;
        tot = 0;
        for(int i=0; i<n; i++) {
            scanf("%d%d%d%d", &x, &y, &a, &b);
            l = 0, r = INF;
            f(x, w, a);
            f(y, h, b);
            if(l<r) {
                p[tot++] = P(l, 0);
                p[tot++] = P(r, 1);
            }
        }
        sort(p, p+tot);
        int cur = 0, ans = 0;
        for(int i=0; i<tot; i++) {
            if(p[i].type == 0) { // 开始事件 +1
                cur++;
                if(cur > ans)    ans = cur;
            } else    cur--; // 结束事件 -1
        }
        printf("%d\n", ans);
    }
    return 0;
}

LA - 3905 ——Meteor 流星

时间: 2024-12-21 06:37:48

LA - 3905 ——Meteor 流星的相关文章

LA 3905 Meteor

给出一些点的初始位置(x, y)及速度(a, b)和一个矩形框,求能同时出现在矩形框内部的点数的最大值. 把每个点进出矩形的时刻分别看做一个事件,则每个点可能对应两个事件,进入事件和离开事件. 按这些事件的发生时间进行排序,然后逐个扫描,遇到进入事件cnt++,遇到离开事件--cnt,用ans记录cnt的最大值. 对时间相同情况的处理,当一个进入事件的时刻和离开事件的时刻相同时,应该先处理离开事件后处理进入事件. 因为速度(a, b)是-10~10的整数,所以乘以LCM(1,2,3,,,10)

LA 3905 Meteor 扫描线

The famous Korean internet company nhn has provided an internet-based photo service which allows The famous Korean internet company users to directly take a photo of an astronomical phenomenon in space by controlling a high-performance telescope owne

3905 - Meteor

The famous Korean internet company nhn has provided an internet-based photo service which allows The famous Korean internet company users to directly take a photo of an astronomical phenomenon in space by controlling a high-performance telescope owne

[2016-03-20][UVALive][3905][Meteor]

时间:2016-03-20 20:14:20 星期日 题目编号:[2016-03-20][UVALive][3905][Meteor] 题目大意:给定一定大小的相框,相框的右下角为坐标原点,给定n个星星的起始位置和运动方向,问相框内最多能捕捉到多少星星 方法: 把星星的运动方向分解成x和y两个方向,计算两个方向经过相框的时间,得到每个星星在相框的时间范围,题目就转换成,最多区间相交问题 计算时间: 计算直线上x为起点,a为增量,经过边界为w的时间对应的l和r 已知 0 < x + at < w

【UVALive】3905 Meteor(扫描线)

题目 传送门:QWQ 分析 扫描线搞一搞. 按左端点排序,左端点相同时按右端点排序. 如果是左端点就$ cnt++ $,否则$ cnt-- $ 统计一下$ Max $就行了 代码 #include <bits/stdc++.h> using namespace std; 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>

D - Meteor

LA 3905 题意:有一个照相机相框,只有在相框内的点才可以被拍到,每一个点都有起始位置(x,y)和速度(a,b),问这个相框最多可以拍摄到多少个点 思路:拍摄肯定是一个瞬时性的动作,那么最终拍摄到点的多少肯定与时间的选取有关,因此可以吧所有的点在相框内出现的时间转化为一个区间. 最后进行遍历,遇到左区间加一,遇到右区间减一 #include <iostream> #include <algorithm> #include <cstdio> using namespa

托福分类词汇

托福分类词汇表(共17类863个常用单词) 一.   psychology 心理 1.       mental 心理的 2.       physical 身体的,物质的,物理的 3.       spiritual 心灵的 4.       conformity 从众 5.       majority 多数人 6.       minority 少数人 7.       threshold judgment (心理学)初始性判断 8.       subject 受实验对象 9.     

计算几何题目分类

转载 一.基础题目 1.1 有固定算法的题目 A, 最近点对问题最近点对问题的算法基于扫描线算法.ZOJ 2107    Quoit Design    典型最近点对问题POJ    3714    Raid    变种最近点对问题 B,最小包围圆最小包围圆的算法是一种增量算法,期望是O(n).ZOJ    1450    Minimal Circle  HDU    3007    Buried memory C,旋转卡壳POJ 3608    Bridge Across Islands   

LA3905 流星(Meteor)

很麻烦的一个题,有很多的技巧可以学到 #include <set> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 100005; const int INF = 0x3fffffff; const int k = 2520;//lcm(1,2,..,10); int w