日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LA3905流星

發(fā)布時間:2025/6/17 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LA3905流星 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:
? ? ? 在一個二維平面上有n個流星,每個流星有自己的初始位置和速度,有一個照相機,張相機的可視范圍是一個矩形框,左下角(0,0)右上角(w ,h),然后問你相機的矩形內(nèi)出現(xiàn)的最多的流星數(shù)是多少??


思路:
? ? ? 感覺是一道很不錯的題目,想到流星數(shù)目,第一反應(yīng)就是可以把他轉(zhuǎn)化成時間段,我們求出每個流星的進入相機時間,和出相機時間,這樣就會得到一個時間段,流星的最大
數(shù)量也就是時間段的最大重疊部分,這個不解釋了應(yīng)該不難理解,現(xiàn)在問題就來了,我們怎么求得所有的時間段呢?一開始我也感覺很麻煩,然后在白書上學了一個比較方便的方法,我們求時間段可以先把流星分解了,x,y單獨算,進入的時間肯定是進x進y的最大值,出去的時間肯定是出x,出y的最小值,這樣我們分別求完之后就ok了,如果L>=R就證明沒有在相機范圍內(nèi)出現(xiàn)過,下面給出求L,R的代碼
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 ,-(double)x / a);
? ? ? R = Min(R ,(double)(w - x) / a);
? ?}
? ?else//往下跑
? ?{
? ? ? L = Max(L ,(double)(w - x) / a);//理解不了的注意這里的a是負的
? ? ? R = Min(R ,-(double)x / a);?
? ?}
? ? ? ? ? ?
}


求x,y的時候都是用的上面的那個,只不過傳的參數(shù)不一樣罷了,具體細節(jié)可以看代碼。
? 這樣我們就得到了所有流星的時間段L,R(L>=R的是不滿足的,直接丟棄),然后就是求區(qū)間的最大重疊面積了,這個也比較好求,如果你不嫌麻煩可以寫線段樹貪心去求,時間復(fù)雜度是O(n*log(n))的,不過有一個更省事更快的方法,就是掃面線法O(n)<其實這么說有漏洞,因為掃描線涉及到排序,排序是O(n*log(n))的,這個地方大家知道就行了>,我們可以把所有端點都扔進結(jié)構(gòu)體數(shù)組里,然后按照時間從小到大排序,如果時間相等那么就后端點在前面(這樣的原因是題目中說在相機邊框上的不算,如果算的話就入端點在前面),排序之后直接掃一遍,遇到前端點就++,后端點就--,過程中最大的值就是答案,這個應(yīng)該很好理解,不理解的在紙上畫一畫,每次變化的時候都是在端點上變化的,這個就是經(jīng)典的掃描線想法,掃描線也可以配合著線段樹應(yīng)用,求重疊面積,體積,周長啥的。這個題目還有一個小小的優(yōu)化(白書上說的),我們可以躲開浮點運算,因為整個程序里涉及到的除法就是除以速度,速度的范圍是絕對值<=10,那么我們直接把被除數(shù)擴大1,2,3..10的最小公倍數(shù)2520倍就行了,這樣保證都是整除,至于為什么我想不用我解釋了。






#include<stdio.h>
#include<string.h>
#include<algorithm>


#define N 100000 + 10


using namespace std;




typedef struct
{
? ? int mk;
? ? double time;
}NODE;


NODE node[N+N];


bool camp(NODE a ,NODE b)
{
? ? ?return a.time < b.time || a.time == b.time && a.mk < b.mk;
}


double Max(double x ,double y)
{
? ? return x > y ? x : y;
}


double Min(double x ,double y)
{
? ? return x < y ? x : y;
}


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 ,-(double)x / a);
? ? ? R = Min(R ,(double)(w - x) / a);
? ?}
? ?else
? ?{
? ? ? L = Max(L ,(double)(w - x) / a);
? ? ? R = Min(R ,-(double)x / a);?
? ?}
? ? ? ? ? ?
}


int main ()
{
? ? int t ,w ,h ,n ,i;
? ? int x ,y ,a ,b;
? ? scanf("%d" ,&t);
? ? while(t--)
? ? {
? ? ? ?scanf("%d %d" ,&w ,&h);
? ? ? ?scanf("%d" ,&n);
? ? ? ?int nowid = 0;
? ? ? ?for(i = 1 ;i <= n ;i ++)
? ? ? ?{
? ? ? ? ? scanf("%d %d %d %d" ,&x ,&y ,&a ,&b);
? ? ? ? ? double L = 0 ,R = 999999999;
? ? ? ? ? Update(x ,a ,w ,L ,R);
? ? ? ? ? Update(y ,b ,h ,L ,R);
? ? ? ? ? if(L < R)
? ? ? ? ? {
? ? ? ? ? ? ?node[++nowid].time = L;
? ? ? ? ? ? ?node[nowid].mk = 1;
? ? ? ? ? ? ?node[++nowid].time = R;
? ? ? ? ? ? ?node[nowid].mk = -1;
? ? ? ? ? }
? ? ? ?}
? ? ? ?int Ans = 0;
? ? ? ?sort(node + 1 ,node + nowid + 1 ,camp);
? ? ? ?int sum = 0;
? ? ? ?for(i = 1 ;i <= nowid ;i ++)
? ? ? ?{
? ? ? ? ? sum += node[i].mk;
? ? ? ? ? if(Ans < sum) Ans = sum;
? ? ? ?}
? ? ? ?printf("%d\n" ,Ans);
? ? }
? ? return 0; ?
}
? ?




//排除浮點型運算
void Update(int x ,int a ,int w ,int& L ,int& R)
{
? ?if(a == 0)
? ?{
? ? ? ?if(x <= 0 || x >= w) R = L - 1;
? ?}
? ?else if(a > 0)?
? ?{
? ? ? L = Max(L ,-x * 2520 / a);
? ? ? R = Min(R ,(w - x) * 2520 / a);
? ?}
? ?else
? ?{
? ? ? L = Max(L ,(w - x) * 2520/ a);
? ? ? R = Min(R ,-x * 2520/ a);?
? ?}
? ? ? ? ? ?
}





總結(jié)

以上是生活随笔為你收集整理的LA3905流星的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。