标签:names include sync tail end 精确 str mil cin
给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的
第一行:n;2≤n≤200000
接下来n行:每行两个实数:x y,表示一个点的行坐标和列坐标,中间用一个空格隔开。
仅一行,一个实数,表示最短距离,精确到小数点后面4位。
0<=x,y<=10^9
思路:运用分治思想,对于n个点,可以分成T(n/2)+T(n/2)的规模,分界线是x坐标的中位数,
假设左边点集合为s1, 右边点集合为s2,那么最小值存在于以下三种情况中。
1.s1中任意两点距离的最小距离
2.s2中任意两点距离的最小距离
3.s1中的点到s2中的点的距离的最小距离
前两部分可以一直分治到底。
第三部分
对于左边每一个点,右边和他产生距离更小的点只能存在于
2d*d的矩形中,而对于2d/3*d/2的矩形,只可能存在一个点,所以点数最多不超过6个
这就使每一层的时间降到O(n),所以总复杂度为O(nlogn)
————————————————
原文链接:https://blog.csdn.net/du_lun/article/details/83344425
#pragma GCC optimize(2) #pragma GCC optimize(3, "Ofast", "inline") #include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; const double INF = 1e18; const double eps = 1e-10; struct node { double x, y; bool operator<(const node &a) const { return x < a.x; } } s[200010], t[200010]; bool cmp(node a, node b) { return a.y < b.y; } double dis(node a, node b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } double cdq(int l, int r) { double d = INF; if (l >= r)return d; int mid = (l + r) >> 1; d = min(d, cdq(l, mid)); d = min(d, cdq(mid + 1, r)); int cnt = 0; for (int i = l; i <= r; i++) { if (fabs(s[i].x - s[mid].x) <= d) t[++cnt] = s[i]; } sort(t + 1, t + 1 + cnt, cmp); for (int i = 1; i <= cnt; i++) { for (int j = i + 1; j <= cnt && fabs(t[i].y - t[j].y) <= d; j++) { if (dis(t[i], t[j]) < d) d = dis(t[i], t[j]); } } return d; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; for (int i = 1; i <= n; i++) cin >> s[i].x >> s[i].y; sort(s + 1, s + 1 + n); cout << fixed << setprecision(4) << (cdq(1, n)) << endl; return 0; }
标签:names include sync tail end 精确 str mil cin
原文地址:https://www.cnblogs.com/nublity/p/11621595.html