题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1107
一样的题目,求一个最近点对。
求最近点对的方法,有很多。时间复杂度上有,n^2的,nlogn的,也有n的。
这里我用的是分治的那种方法。nlogn的方法。写的很挫,第一次写。慢慢优化。也没有精度判断。
Code:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 1e5 + 4; const double INF = 1e100; struct POINT { double x, y; }p[N], tmp[N]; int n; double Distance(POINT a, POINT b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } bool cmpx(POINT a, POINT b) { if(a.x < b.x) return true; else if(a.x == b.x && a.y < b.y) return true; return false; } bool cmpy(POINT a, POINT b) { if(a.y < b.y) return true; else if(a.y == b.y && a.x < b.x) return true; return false; } double Near_Pair_Point(int l, int r) { if(l == r) return INF; if(l + 1 == r) return Distance(p[l], p[r]); if(l + 2 == r) return min(Distance(p[l], p[l + 1]), min(Distance(p[l], p[r]), Distance(p[l + 1], p[r]))); int mid = (l + r) / 2; double ans = min(Near_Pair_Point(l, mid), Near_Pair_Point(mid + 1, r)); int top = 0; for(int i = mid; i >= l && p[mid].x - p[i].x <= ans; i --) tmp[top ++] = p[i]; for(int i = mid + 1; i <= r && p[i].x - p[mid].x <= ans; i ++) tmp[top ++] = p[i]; sort(tmp, tmp + top, cmpy); for(int i = 0; i < top - 1; i ++){ for(int j = i + 1; j < top; j ++){ if(Distance(tmp[i], tmp[j]) > ans) break; ans = min(ans, Distance(tmp[i], tmp[j])); } } return ans; } int main() { // printf("%lf\n", INF); // freopen("1.txt", "r", stdin); while(scanf("%d", &n) && n){ for(int i = 0; i < n; i ++){ scanf("%lf %lf", &p[i].x, &p[i].y); } sort(p, p + n , cmpx); printf("%.2lf\n", Near_Pair_Point(0, n - 1) / 2.0); } return 0; }
计算几何继续。。。。。。深搜,递归神马的太需要学习了。。。