• [BZOJ2458][BeiJing2011]最小三角形(分治)


    求平面上n个点组成的周长最小的三角形。

    回忆平面最近点对的做法,找到横坐标的中点mid分治到两边,合并时考虑离mid横坐标不超过当前最小值d的所有点,按y排序后暴力更新答案。

    这个题也一样,先分治到两边,然后取出所有离mid横坐标不超过当前最小值/2的点,按y排序后选择三个总坐标不超过当前最小值/2的点更新答案。

    按y排序在递归上来时归并,复杂度O(nlogn)。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 using namespace std;
     7 
     8 const int N=200010;
     9 int n;
    10 double ans=1e10;
    11 struct P{ int x,y; }p[N],p2[N];
    12 bool cmp(const P &a,const P &b){ return a.x<b.x; }
    13 double sqr(double x){ return x*x; }
    14 double dis(int a,int b){ return sqrt(sqr(p[a].x-p[b].x)+sqr(p[a].y-p[b].y)); }
    15 
    16 void solve(int l,int r){
    17     if (r<=l) return;
    18     if (r-l==1){ if (p[l].y>p[r].y) swap(p[l],p[r]); }
    19     int mid=(l+r)>>1,tmp=p[mid].x;
    20     solve(l,mid); solve(mid+1,r);
    21     for (int i=l,j=mid+1,w=l-1; i<=mid || j<=r; )
    22         if ((i<=mid) && (j>r || p[j].y>p[i].y)) p2[++w]=p[i++]; else p2[++w]=p[j++];
    23     rep(i,l,r) p[i]=p2[i];
    24     rep(i,l+2,r) if (2*abs(p[i].x-tmp)<=ans)
    25         for (int j=i-2; j>=l && 2*(p[i].y-p[j].y)<=ans; j--)
    26             if (2*abs(p[j].x-tmp)<=ans)
    27                 rep(k,j+1,i-1) ans=min(ans,dis(i,j)+dis(j,k)+dis(i,k));
    28 }
    29 
    30 int main(){
    31     freopen("bzoj2458.in","r",stdin);
    32     freopen("bzoj2458.out","w",stdout);
    33     scanf("%d",&n);
    34     rep(i,1,n) scanf("%d%d",&p[i].x,&p[i].y);
    35     sort(p+1,p+n+1,cmp);
    36     solve(1,n); printf("%.6lf
    ",ans);
    37     return 0;
    38 }
  • 相关阅读:
    大话设计模式读书笔记--4.代理模式
    大话设计模式读书笔记--3.装饰模式
    大话设计模式读书笔记--2.策略模式
    大话设计模式读书笔记--1.简单工厂模式
    redis分片
    redis主从同步
    用Jedis连接Redis
    redis的数据类型和指令
    使用可视化工具redisclient连接redis
    《深入浅出通信原理》参考资料
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9858326.html
Copyright © 2020-2023  润新知