• BZOJ 2458


    http://blog.csdn.net/PoPoQQQ/article/details/43155749

    1.随便去三个点构成三角形的轴承作为ans的初值

    2.按照x排序

    3.分治处理[l,r]内的三角形的最小周长

    4.分治[l,r]=>[l,mid]和[mid+1,r]

    5.两个子区间的情况都以处理完毕,处理当前区间中点构成的三角形

    6.按照纵坐标归并排序,将本层中与点mid的横坐标之差不超过ans/2的点拎出来

    7.维护双指针,保证内部点纵坐标之差和横坐标与中线位置之差不超过ans/2,对于范围内的点暴力查找最小三角形即可

    显而易见,期望的复杂度可能为O(nlogn)[逃]

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<math.h>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    #define ROF(i,s,t) for(register int i=s;i>=t;--i)
    using namespace std;
    typedef double db;
    int n;
    db ans;
    const int N=200011;
    struct point{
    	db x,y;
    	inline bool operator<(point A)const{
    		return x<A.x||(x==A.x&&y<A.y);
    	}
    }t[N],p[N];
    inline double work(point A,point B){
    	return 1.00*sqrt((db)1.00*(A.x-B.x)*(A.x-B.x)+(db)1.00*(A.y-B.y)*(A.y-B.y));
    }
    inline db abs(db x){
    	return x>0?x:-x;
    }
    inline db min(db a,db b){
    	return a<b?a:b;
    } 
    inline void solve(int l,int r){
    	if(l==r)return;
    	if(l+1==r){
    		if(p[r].y<p[l].y)
    			swap(p[r],p[l]);
    		return; 
    	} 
    	int mid=(l+r)>>1;
    	int tmp=p[mid].x;
    	solve(l,mid);solve(mid+1,r);
    	int idx1=l,idx2=mid+1;
    	FOR(i,l,r)
    		t[i]=(idx2>r||(idx1<=mid&&p[idx1].y<p[idx2].y)?p[idx1++]:p[idx2++]);
    	FOR(i,l,r)p[i]=t[i]; 
    	for(register int i=l,tail=l;i<=r;++i)  
            if(1.00*abs(p[i].x-tmp)<ans/2){  
                for(;p[i].y-p[tail].y>ans/2;++tail);  
                for(register int j=tail;j<i-1;++j)  
                    if(1.00*abs(p[j].x-tmp)<ans/2)  
                        if(p[i].y-p[j].y<ans/2)  
                            for(register int k=j+1;k<i;++k)  
                                ans=min(ans,work(p[i],p[j])+work(p[i],p[k])+work(p[j],p[k]));  
            }  
    }
    int main(){
        scanf("%d",&n);
        FOR(i,1,n)scanf("%lf%lf",&p[i].x,&p[i].y);
        sort(p+1,p+n+1);
        ans=work(p[1],p[2])+work(p[3],p[2])+work(p[1],p[3]);
        solve(1,n);
        printf("%.6lf",ans);
        return 0;
    }
    

      

  • 相关阅读:
    TreeMap
    索引
    B-树、B+树
    硬盘速度、存储方式
    2-3树
    多叉树、2-3-4树
    红黑树
    平衡树、AVL树
    树、多路树、二叉树
    Java实现后缀表达式建立表达式树
  • 原文地址:https://www.cnblogs.com/Stump/p/7908757.html
Copyright © 2020-2023  润新知