zoukankan      html  css  js  c++  java
  • [BZOJ2458][BeiJing2011]最小三角形

    [BZOJ2458][BeiJing2011]最小三角形

    试题描述

    Xaviera现在遇到了一个有趣的问题。
    平面上有N个点,Xaviera想找出周长最小的三角形。
    由于点非常多,分布也非常乱,所以Xaviera想请你来解决这个问题。
    为了减小问题的难度,这里的三角形也包括共线的三点。

    输入

    第一行包含一个整数N表示点的个数。
    接下来N行每行有两个整数,表示这个点的坐标。

    输出

    输出只有一行,包含一个6位小数,为周长最短的三角形的周长(四舍五入)。

    输入示例

    4
    1 1
    2 3
    3 3
    3 4

    输出示例

    3.414214

    数据规模及约定

    100%的数据中N≤200000。

    题解

    平面分治。类似求平面最近点对。

    首先对所有点按 x 坐标排序,每次选取中间的 x 作为分界点(令过这个点的竖直线为中线),左边、右边分别递归求,设求得的答案为 C;然后考虑跨中线的点对答案的贡献,找到中线左右扩展 C / 2 距离的矩形内的所有点,然后用一个边长为 C 的正方形从下往上平移,可以证明每次正方形框住的点只有常数个,暴力求正方形内所有点的答案即可(显然最终答案的那三个点是不可能在这个正方形之外的)。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 200010
    #define LL long long
    const double ooe = 1.0 / 0.0, eps = 1e-5;
    
    struct Vec {
    	LL x, y;
    	Vec() {}
    	Vec(int _, int __): x(_), y(__) {}
    	Vec operator - (const Vec& t) const { return Vec(x - t.x, y - t.y); }
    	double length() { return sqrt(x * x + y * y); }
    	bool operator < (const Vec& t) const { return x != t.x ? x < t.x : y < t.y; }
    } ps[maxn], tmp[maxn];
    bool cmp(Vec a, Vec b) { return a.y < b.y; }
    
    int n, cnt;
    
    double solve(int l, int r) {
    	if(r - l + 1 < 3) return ooe;
    	int mid = l + r >> 1;
    	double C = min(solve(l, mid), solve(mid + 1, r)), ans = C;
    	cnt = 0;
    	for(int i = l; i <= r; i++) if(abs(ps[i].x - ps[mid].x) - C * 0.5 <= eps) tmp[++cnt] = ps[i];
    	sort(tmp + 1, tmp + cnt + 1, cmp);
    	int L = 1, R = 3;
    	for(; R <= cnt; R++) {
    		while(tmp[R].y - tmp[L].y - C > eps) L++;
    		for(int x = L; x <= R; x++)
    			for(int y = x + 1; y <= R; y++)
    				for(int z = y + 1; z <= R; z++)
    					ans = min(ans, (tmp[x] - tmp[y]).length() + (tmp[x] - tmp[z]).length() + (tmp[y] - tmp[z]).length());
    	}
    	return ans;
    }
    
    int main() {
    	n = read();
    	for(int i = 1; i <= n; i++) {
    		int x = read(), y = read();
    		ps[i] = Vec(x, y);
    	}
    	
    	sort(ps + 1, ps + n + 1);
    	
    	printf("%.6lf
    ", solve(1, n));
    	
    	return 0;
    }
    
  • 相关阅读:
    AutomaticallyProfile 自动化引擎 MyBatis和DB沟通的引擎 (根据数据库信息自动给生成实体类那些...)
    经典aop,
    IOC和DI区别,aop的第一个案例,注入方式(7种),aop的7个专业术语,注解的DI,代理(动态代理,静态代理)
    AOP(AOP概念,AOP专业术语,单例模式,bean的id和name属性,基于xml的DI, 构造注入,命名空间p注入,集合属性注入, List 配置文件)
    ajax
    spring基础
    一对多,多对一,自关联,多对多,一级缓存,二级缓存
    hql语法
    sql操作语言
    Oracle函数
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6953990.html
Copyright © 2011-2022 走看看