zoukankan      html  css  js  c++  java
  • BZOJ 2458: [BeiJing2011]最小三角形 (分治)

    分治就是了.

    类似于分治找最近/远点对.

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    const double eps = 1e-13;
    const int MAXN = 200005;
    const double INF = 1e15;
    #define sqr(x) ((x)*(x))
    struct Point {
    	double x, y;
    	Point(){}
    	Point(double x, double y):x(x), y(y){}
    	inline friend double dist(const Point &A, const Point &B) {
    		return sqrt(sqr(A.x-B.x) + sqr(A.y-B.y));
    	}
    	inline friend double S_tri(const Point &A, const Point &B, const Point &C) {
    		return dist(A, B) + dist(A, C) + dist(B, C);
    	}
    }a[MAXN];
    inline bool cmpx(const Point &A, const Point &B) { return A.x < B.x; }
    inline bool cmpy(const Point &A, const Point &B) { return A.y < B.y; }
    int n;
    double solve(int l, int r) {
    	if(r-l < 2) return INF;
    	if(r-l == 2) return S_tri(a[l], a[l+1], a[l+2]);
    	int mid = (l + r) >> 1; double X = a[mid].x;
    	double re = min(solve(l, mid-1), solve(mid+1, r));
    	int st = l, ed = r;
    	while(X-a[st].x > re/2) ++st;
    	while(a[ed].x-X > re/2) --ed;
    	sort(a + st, a + ed + 1, cmpy);
    	for(int i = st; i <= ed; ++i)
    		for(int j = i+1; j <= ed; ++j)
    			if(dist(a[i], a[j]) + eps > re/2) break; //剪枝必须加
    			else for(int k = j+1; k <= ed; ++k)
    					if(dist(a[i], a[k]) + eps > re/2) break;
    					else re = min(re, S_tri(a[i], a[j], a[k]));
    	sort(a + st, a + ed + 1, cmpx);
    	return re;
    }
    int main() {
    	scanf("%d", &n);
    	for(int i = 1; i <= n; ++i)
    		scanf("%lf%lf", &a[i].x, &a[i].y);
    	sort(a + 1, a + n + 1, cmpx);
    	printf("%.6f
    ", solve(1, n));
    }
    
    
  • 相关阅读:
    CORS跨域漏洞学习
    CVE-2020-0796漏洞复现(RCE)
    Wfuzz使用学习
    DNSlog注入学习
    一些CTF练习记录
    数据结构与算法(十三):赫夫曼树
    数据结构与算法(十二):堆排序
    博客园自定义代码块样式
    Nginx入门(二):常用功能配置
    数据结构与算法(十一):二叉树
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039301.html
Copyright © 2011-2022 走看看