題目描述:
給定平面上n個點,找出其中的一對點的距離,使得在這n個點的所有點對中,該距離為所有點對中最小的。
既然是暴力做法,那肯定是非常非常暴力的做法,無疑是列舉。列舉i從1~n,j從i+1~n,用距離公式計算出第i個點和第j個點的距離,然後找到最小值即可。放一道模板題吧!
ac**:
#include#include#include#define ll long long
using namespace std;
ll n,mn;
ll x[10005],y[10005],now;
double ans;
inline ll dis(ll x1,ll y1,ll x2,ll y2)
int main()
mn=dis(x[1],y[1],x[2],y[2]);
for(int i=1;i<=n;i++)
} } printf("%.4lf",sqrt(mn));
return 0;
}
有時候題目的資料範圍超過了暴力能接受的範圍怎麼辦呢?這時我們考慮一種分治演算法。我們先將所有點按x座標公升序排序一遍。然後考慮分治,對於當前要處理的[l,r]區間內的所有點(若l==r返回inf),我們將其按照橫座標均分為一半對一半,並在他們直接劃出一條分界線。左右兩邊各自算出其包含範圍內的最小值,然後怎麼合併兩邊的點呢?我們算出左右兩邊的最小值分別為d1 , d2(遞迴處理)。我們再設乙個d=min(d1,d2)。很明顯,左右兩邊的點只有到分界線距離在d以內才有機會更新最小值,而且我們還能發現這樣的點不超過8個,可以很大程度縮小搜尋範圍。於是我們就在很短的時間內合併成功了!這種做法也丟一道模板題吧!
ac**:
#include#include#include#include#define ll long long
using namespace std;
const int maxn=200005;
struct nodea[maxn];
int n,tmp[maxn];ll inf;
inline ll dis(node s1,node s2)
inline ll mn(ll x,ll y)
bool cmp(node s1,node s2)
}for(int i=1;i<=k;i++)
}return d;
}inline ll read()
while(c>='0'&&c<='9')
return x*f;
}int main()
sort(a+1,a+1+n,cmp);
printf("%.4lf\n",sqrt(merge(1,n)));
return 0;
}
平面最近點對
求點集中的最近點對有以下兩種方法 設p1 x1,y1 p2 x2,y2 pn xn,yn 是平面上n個點構成的集合s,設計演算法找出集合s中距離最近的點對。1 蠻力法 適用於點的數目比較小的情況下 1 演算法描述 已知集合s中有n個點,一共可以組成n n 1 2對點對,蠻力法就是對這n n 1 2 ...
平面最近點對
求點集中的最近點對有以下兩種方法 設p1 x1,y1 p2 x2,y2 pn xn,yn 是平面上n個點構成的集合s,設計演算法找出集合s中距離最近的點對。1 蠻力法 適用於點的數目比較小的情況下 1 演算法描述 已知集合s中有n個點,一共可以組成n n 1 2對點對,蠻力法就是對這n n 1 2對...
平面最近點對
求點集中的最近點對有以下兩種方法 設p1 x1,y1 p2 x2,y2 pn xn,yn 是平面上n個點構成的集合s,設計演算法找出集合s中距離最近的點對。1 蠻力法 適用於點的數目比較小的情況下 1 演算法描述 已知集合s中有n個點,一共可以組成n n 1 2對點對,蠻力法就是對這n n 1 2對...