bzoj 2458: [BeiJing2011]最小三角形 题解

来源:互联网 发布:仁和知柏地黄丸怎么样 编辑:程序博客网 时间:2024/06/10 16:08

看了蒋学长的博客

我们定义一个函数设f(l,r)表示从第l个点到第r个点之间的最小三角形

然后每一次都二分区间求f(l,mid)f(mid+1,r)然后发现这样没有避免三角形跨过mid的情况

所以再枚举就可以辣

可以证明复杂度这里就不说了(我不会啊)

下面是代码

#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<cstdio>#define N 200003#define INF 210000000000.0using namespace std;struct arr{int x,y;}a[N],num[N];int n,i,test;inline bool cmpx(const arr &a,const arr &b){return a.x<b.x;}inline bool cmpy(const arr &a,const arr &b){return a.y<b.y;}inline double dis(const arr &a,const arr &b){double ans=sqrt((a.x-b.x)*1.*(a.x-b.x)+(a.y-b.y)*1.*(a.y-b.y));return ans;}inline double work(int l,int r){if(r-l<=1){return INF;}if(l+2==r){return dis(a[l],a[l+1])+dis(a[l],a[r])+dis(a[l+1],a[r]);}int mid=(l+r)>>1;double d1=work(l,mid),d2=work(mid+1,r);double D=min(d1,d2),ans=D,DD=D/2.0;int cnt=0;for(int i=l;i<=r;i++){if(fabs(a[mid].x-a[i].x)<=DD){num[++cnt]=a[i];}}sort(num+1,num+cnt+1,cmpy);for(int i=1;i<cnt-1;i++){for(int j=i+1;j<cnt;j++){if(num[j].y-num[i].y>DD){break;}for(int k=j+1;k<=cnt;k++){if(num[k].y-num[i].y>DD){break;}double temp=dis(num[i],num[j])+dis(num[i],num[k])+dis(num[j],num[k]);        ans=min(ans,temp);}}}return ans;}int main(){cin>>n;for(int i=1;i<=n;i++){cin>>a[i].x>>a[i].y;}sort(a+1,a+n+1,cmpx);printf("%.6lf",work(1,n));return 0;}/*in:41 12 33 33 4out:3.414214*/


1 0
原创粉丝点击