【HDU 1007】Quoit Design

http://acm.hdu.edu.cn/showproblem.php?pid=1007
最近欧式距离模板题。
用分治大法(分治的函数名用cdq纯属个人习惯_(:з」∠)_)
一开始狂M。

后来判断n是否为0就不M了QwQ

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100003;

struct Point {double x, y;} P[N];
int n, tot, id[N];

bool cmp_x(Point A, Point B) {return A.x < B.x;}

bool cmp_y(int A, int B) {return P[A].y < P[B].y;}

double sqr(double x) {return x * x;}

double dis(int x, int y) {return sqrt(sqr(P[x].x - P[y].x) + sqr(P[x].y - P[y].y));}

double cdq(int l, int r) {
	if (r - l == 1) return dis(l, r);
	if (r - l == 2) return min(dis(l, l + 1), min(dis(l, r), dis(l + 1, r)));
	int mid = (l + r) >> 1;
	double d = min(cdq(l, mid), cdq(mid + 1, r));
	
	tot = 0; double left = P[mid].x - d, right = P[mid].x + d;
	for(int i = l; i <= r; ++i)
		if (left <= P[i].x && P[i].x <= right)
			id[++tot] = i;
	sort(id + 1, id + tot + 1, cmp_y);
	for(int i = 1; i <= tot; ++i)
		for(int j = i + 1; j <= tot; ++j) {
			if (P[id[j]].y - P[id[i]].y > d) break;
			d = min(d, dis(id[j], id[i]));
		}
	return d;
}

int main() {
	while (~scanf("%d", &n)) {
		if (n == 0) break; 
		for(int i = 1; i <= n; ++i)
			scanf("%lf%lf", &P[i].x, &P[i].y);
		sort(P + 1, P + n + 1, cmp_x);
		printf("%.2lf
", cdq(1, n) / 2);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/abclzr/p/5930837.html