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 }