UVALive 3905 Meteor (扫描线)
生活随笔
收集整理的這篇文章主要介紹了
UVALive 3905 Meteor (扫描线)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接 https://vjudge.net/problem/UVALive-3905
第一次學到這個。對于每一顆流星,我們求出它在矩形框內待的時間段 L~R,把L和R按照不同的類型加入結構體。我們先按照時間從小到大排序,然后逐個掃描,遇到左端點L說明這個時刻流星已進入矩形框,個數加1,遇到右端點R個數減1,然后不斷更新最大值。
最后要注意開始時間與結束事件重疊的情況,即當某個時刻開始時間與結束事件重疊。如果是先加后減的話,那么最大值會是2,相反先減后加答案就會是1。顯然,在這里,后者才是正確的,因為由題意所有時間區間結尾開區間。
我認為求時間的區間這部分比較難以求解
?
#include<bits/stdc++.h> using namespace std; const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; struct node{double t;int type;//0表示右端點,1表示左端點node(double _t = 0, int _type = 0) :t(_t), type(_type){};bool operator<(const node &other) const{if (t == other.t) return type < other.type;return t < other.t;} }arr[N]; int ans,tot,w,h,n; //解不等式 0< x + v*t <w // void update(int x, int v,int w, double &l, double &r) {if (v == 0){if (x <= 0 || x >= w) r = l - 1;//這種情況肯定不會出現在矩形內部 }else if (v>0) //-x< v*t < w-x ,這里v>0,兩邊同時除以v,方向不邊 {l = max(l, -1.0*x / v);r = min(r, 1.0*(w - x) / v);}else//v<0,兩邊同時除v,方向改變 {l = max(l, 1.0*(w - x) / v);r = min(r, -1.0*x / v);} } int main() {int t;cin >> t;while (t--){tot = 0;ans = 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 = INF;update(x, a, w,l, r);update(y, b, h,l, r);if (r>l){arr[tot++] = node(l, 1);arr[tot++] = node(r, 0);}}sort(arr, arr + tot);int cnt = 0;for (int i = 0; i < tot; i++){if (arr[i].type) cnt++;else cnt--;ans = max(ans, cnt);}cout << ans << endl;}return 0; }?
轉載于:https://www.cnblogs.com/xiaoguapi/p/10540962.html
總結
以上是生活随笔為你收集整理的UVALive 3905 Meteor (扫描线)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Centos系统更改yum源为163
- 下一篇: Java并发编程75道面试题及答案