題目概述:
給出n個點,求n個點兩兩之間的最小距離。
大致思路:
直接暴力的話複雜度是o(n²),這個複雜度在n=100000的時候是無法承受的,那麼我們就需要降低複雜度了。
對平面內任一鉛垂線來說,這個最小距離要麼在這條線左,要麼在這條線右,要麼跨過這條線,這個時候想到了什麼?二分!
考慮用二分來解決這個題目,鉛垂線直接找最中間的點的x座標即可,這樣可以保證二分的複雜度在o(logn),這樣的話就只需要解決跨過鉛垂線的情況了。
假設左邊和右邊的最小距離的較小值為d,那麼實際上跨過鉛垂線又是最小距離的點對他們的x座標與鉛垂線的水平距離一定不會超過d,看上去只需要列舉所有水平距離小於d的點對就好了,不過如果對乙個 半區間 來說,它裡面的所有點都聚集在距離小於d的地方怎麼辦?這個時候按上述思路列舉顯然複雜度會退化到o(n²)。
其實看懂上面列舉水平距離的做法這個問題就很好解決了,因為顯然垂直距離也滿足這個條件。所以列舉是只需要列舉水平,垂直距離均小於d的點對即可。
注意先對所有點按x,y公升序排列。
複雜度分析:
理論上來說二分複雜度是o(nlogn),所以複雜度應該取決於解決跨過鉛垂線時列舉的點對的數目,只要出題人不刻意卡資料的話,可以大致認為複雜度為o(nlogn)。
**:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12using
namespace
std;
1314
#define sacnf scanf
15#define scnaf scanf
16#define maxn 100010
17#define maxm 26
18#define inf 1061109567
19#define eps 0.00001
20const
double pi=acos(-1.0
);21
#define mod 1000033
22#define maxnum 10000
23void swap(int &a,int &b)
24int abs(int x)
25 typedef long
long
ll;26 typedef unsigned int
uint;27
28struct
node
2936
} a[maxn];
3738
double dist(node a,node b)
3940
double query(int l,int
r)4155}
56return
d;57}58
59int
main()
6072 sort(a+1,a+1+n);
73double ans=query(1
,n);
74 printf("
%.2lf\n
",sqrt(ans)/2.0
);75}76
//clock_t ed=clock();
77//
printf("\n\ntime used : %.5lf ms.\n",(double)(ed-st)/clocks_per_sec);
78return0;
79 }
(模板)hdoj1007(分治求平面最小點對)
題意 給定n個點,求平面距離最小點對的距離除2。思路 分治求最小點對,對區間 l,r 遞迴求 l,mid 和 mid 1,r 的最小點對,取兩者中的小者設為d。然後處理乙個點在左區間,乙個點在右區間的情況。乙個點p在左區間,如果使它與右區間q乙個點距離小於d的話,那麼p到mid的距離一定小於的,q也...
二分法解題報告
題目 派 描述 我的生日要到了!根據習俗,我需要將一些派分給大家。我有 n個不同口味 不同大小的派。有 f個朋友會來參加我的派對,每個人會拿到一塊派 必須乙個派的一塊,不能由幾個派的小塊拼成 可以是一整個派 我的朋友們都特別小氣,如果有人拿到更大的一塊,就會開始抱怨。因此所有人拿到的派是同樣大小的 ...
BZOJ 1052 二分答案 解題報告
1052 haoi2007 覆蓋問題 description 某人在山上種了n棵小樹苗。冬天來了,溫度急速下降,小樹苗脆弱得不堪一擊,於是樹主人想用一些塑料薄 膜把這些小樹遮蓋起來,經過一番長久的思考,他決定用3個l l的正方形塑料薄膜將小樹遮起來。我們不妨將山建 立乙個平面直角座標系,設第i棵小樹...