UVA - 1398 Meteor

本文介绍了一种通过读取输入文件来模拟流星轨迹并计算在某一时刻最多能看到多少颗流星的方法。具体步骤包括:解析输入文件获取每个流星的初始位置和速度矢量,通过数学方法确定流星进入和离开望远镜视野的时间点,最后使用扫描线算法计算在任意时刻的最大可见流星数量。

 

Input
Your program is to read the input from standard input. The input consists of T test cases. The
number of test cases T is given in the first line of the input. Each test case starts with a line containing
two integers w and h (1 ≤ w, h ≤ 100, 000), the width and height of the telescope frame, which are
separated by single space. The second line contains an integer n, the number of input points (meteors),
1 ≤ n ≤ 100, 000. Each of the next n lines contain four integers x i , y i , a i , and b i ; (x i , y i ) is the starting
point p i and (a i , b i ) is the nonzero velocity vector v i of the i-th meteor; x i and y i are integer values
between -200,000 and 200,000, and a i and b i are integer values between -10 and 10. Note that at least
one of a i and b i is not zero. These four values are separated by single spaces. We assume that all
starting points p i are distinct.
Output
Your program is to write to standard output. Print the maximum number of meteors which can be in
the telescope frame at some moment.
Sample Input
2
4 2
2
-1 1 1 -1
5 2 -1 -1
13 6
7
3 -2 1 3
6 9 -2 -1
8 0 -1 -1
7 6 10 0
11 -2 2 1
-2 4 6 -1
3 2 -5 -1
Sample Output
1
2

 

1.如何求交点(列不等式,求t的范围,注意速度的正负)

2.如何求某时间内最大值(扫描线进行端点的扫描,所有端点排序,左端点+,右端点-)

#include <cstdio>
#include <algorithm>
#include <iostream>

using namespace std;

struct Event {
    double x; //端点时间值,用于排序
    bool type; //是否为右端点

    bool operator<(const Event &e) {
        return x < e.x || (x == e.x and type); //右端点先排前面
    }
} events[100000 * 2];

//由0<x+vt<w得出
void update(int x, int w, int v, double &L, double &R) {
    if (v == 0) {
        if (x <= 0 || x >= w)
            R = L - 1;
    } else if (v > 0) {
        L = max((double) -x / v, L);
        R = min((double) (w - x) / v, R);
    } else {
        L = max((double) (w - x) / v, L);
        R = min((double) -x / v, R);
    }
}

int main() {
    int T, w, h, n;
    cin >> T;
    while (T--) {
        cin >> w >> h;
        int x, y, a, b, e = 0, ans = 0;
        cin >> n;
        for (int i = 0; i < n; ++i) {
            cin >> x >> y >> a >> b;
            double L = 0, R = 1e6;
            update(x, w, a, L, R);
            update(y, h, b, L, R);
            if (L < R) {
                events[e++] = {L, 0};
                events[e++] = {R, 1};
            }
        }
        sort(events, events + e);
        for (int i = 0, cnt = 0; i < e; ++i) {
            cnt += events[i].type ? -1 : 1; //右端点-左端点+
            ans = max(ans, cnt);
        }
        cout << ans << endl;
    }
}

 

转载于:https://www.cnblogs.com/wangsong/p/7631453.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值