LA3905 Meteor

https://vjudge.net/problem/UVALive-3905

 

 

 

计算出每个点在相框中的时间段,扫描线做即可

 

关键在如何快速计算每个点在相框中的时间段。对每个点进行运动分解,进入的时间L是x进入和y进入的最大,退出时间R是x退出和y退出的最小,画图看一下即可

画图同时可以发现不经过相框的时候会导致L >= R

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #define min(a, b) ((a) < (b) ? (a) : (b))
 9 #define max(a, b) ((a) > (b) ? (a) : (b))
10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
11 inline void swap(int &a, int &b)
12 {
13     int tmp = a;a = b;b = tmp;
14 }
15 inline void read(int &x)
16 {
17     x = 0;char ch = getchar(), c = ch;
18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
20     if(c == '-') x = -x;
21 }
22 
23 const int INF = 0x3f3f3f3f;
24 const int MAXN = 100000 + 10;
25 
26 int tt,w,h,n,x[MAXN],y[MAXN],a[MAXN],b[MAXN],flag[MAXN << 1], cnt[MAXN << 1], tot, t[MAXN << 1], ans, tag;
27 
28 bool cmp(int a, int b)
29 {
30     return t[a] == t[b] ? flag[a] > flag[b] : t[a] < t[b];
31 }
32 
33 inline void update(int x, int a, int w, int &L, int &R)
34 {
35     if(a == 0)
36     {
37         if(x <= 0 || x >= w) R = L - 1; 
38     }
39     else if(a > 0)
40     {
41         L = max(L, -x * 2520 / a);
42         R = min(R, (w - x) * 2520 / a); 
43     }
44     else 
45     {
46         L = max(L, (w - x) * 2520 / a);
47         R = min(R, -x * 2520 / a); 
48     }
49 }
50 
51 int main()
52 {
53     read(tt);
54     for(;tt;--tt)
55     {
56         read(w), read(h), read(n);
57         for(register int i = 1;i <= n;++ i) read(x[i]), read(y[i]), read(a[i]), read(b[i]);
58         tot = 0;
59         for(register int i = 1;i <= n;++ i)
60         {
61             int L = 0, R = INF;
62             update(x[i], a[i], w, L, R);
63             update(y[i], b[i], h, L, R);
64             if(L < R)
65             {
66                 t[++tot] = L;flag[tot] = 0;cnt[tot] = tot;
67                 t[++tot] = R;flag[tot] = 1;cnt[tot] = tot;
68             }
69         }
70         std::sort(cnt + 1, cnt + 1 + tot, cmp);
71         ans = tag = 0;
72         for(register int i = 1;i <= tot;++ i)
73         {
74             if(flag[cnt[i]]) -- tag;
75             else ++ tag;
76             ans = max(ans, tag);
77         }
78         printf("%d\n", ans);
79     }
80     return 0;
81 } 
LA3905

 

posted @ 2018-01-15 15:38  嘒彼小星  阅读(144)  评论(0编辑  收藏  举报