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

    2458: [BeiJing2011]最小三角形

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1671  Solved: 582
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    4
    1 1
    2 3
    3 3
    3 4

    Sample Output

    3.414214


    HINT

    100%的数据中N≤200000。

    Source

    分析:平面上最近距离点的模板.实际上就是把求两个点变成了求三个点,多一层枚举即可.一个小小的优化:若左右搜到的答案为res,则找的点到中间点的x坐标差的绝对值≤res / 2.
              尽管读入是整数,但最好还是用实数读入,不然以后处理进制转换很容易WA.
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n,cnt;
    
    struct node
    {
        double x,y;
    }e[200010],p[200010];
    
    double dist(node a,node b)
    {
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    
    bool cmp(node a,node b)
    {
        return a.x < b.x;
    }
    
    bool cmp2(node a,node b)
    {
        return a.y < b.y;
    }
    
    double solve(int l,int r)
    {
        if (l + 2 == r)
            return dist(e[l],e[l + 1]) + dist(e[l + 1],e[r]) + dist(e[l],e[r]);
        if (l + 1 >= r)
            return 1e20;
        int mid = (l + r) >> 1;
        double res = min(solve(l,mid - 1),solve(mid + 1,r));
        cnt = 0;
        for (int i = l; i <= r; i++)
            if (fabs(e[mid].x - e[i].x) <= res / 2.0)
                p[++cnt] = e[i];
        sort(p + 1,p + 1 + cnt,cmp2);
        for (int i = 1; i <= cnt; i++)
        {
            for (int j = i + 1; j <= cnt; j++)
            {
                if (p[j].y - p[i].y > res / 2.0)
                    break;
                for (int k = j + 1; k <= cnt; k++)
                {
                    if (p[k].y - p[i].y > res / 2.0)
                        break;
                    res = min(res,dist(p[i],p[j]) + dist(p[i],p[k]) + dist(p[j],p[k]));
                }
            }
        }
        return res;
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i = 1; i <= n; i++)
            scanf("%lf%lf",&e[i].x,&e[i].y);
        sort(e + 1,e + 1 + n,cmp);
        printf("%.6lf
    ",solve(1,n));
    
        return 0;
    }
  • 相关阅读:
    表格行内编辑增删改查
    rpc远程调用开发
    gdb调试程序
    Makefile文件编写
    CentOS6.6源码编译升级GCC至4.8.2
    linux 下C语言编程库文件处理与Makefile编写
    laravel队列-让守护进程处理耗时任务
    回顾javase点滴
    服务端生成word并压缩打包下载
    pytest框架插件(用例依赖、多重校验、执行顺序、失败重跑、重复执行、标记)
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8186379.html
Copyright © 2011-2022 走看看