UVA - 1398 Meteor

题目大意:给出一个w和h,表示说照相机可以照到的范围,然后有n个彗星,给出起始坐标以及移动的向量,问说一张照片最多有几个彗星。

解题思路:根据坐标和移动向量求出进入范围和离开范围的时间,按照时间进行排序,然后没进一次加1,出一个减1,维护最大值,注意有可能存在彗星不进入范围。

#include <cstdio>
#include <algorithm>
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 > 0) {
        L = max(L, 1.0 * (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 * (0 - x) / a);
    }
}

struct E {
    double p;
    int type; bool operator < (const E& a) const {
        return p < a.p || (p == a.p && type < a.type);
    }
} A[200005];

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        int w, h, n, cnt = 0;
        scanf("%d%d%d", &w, &h, &n);

        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 (L < R) {
                A[cnt].p = L;
                A[cnt++].type = 1;
                A[cnt].p = R;
                A[cnt++].type = 0;
            }

        }

        sort(A, A + cnt);
        int MAX = 0, ans = 0;
        for (int i = 0; i < cnt; ++i)
            if (A[i].type == 1) {
                ans++;
                if (ans > MAX)
                    MAX = ans;
            } else
                ans--;

        printf("%d\n", MAX);
    }
    return 0;
}

你可能感兴趣的:(UVA - 1398 Meteor)