首页 > 代码库 > bzoj2458: [BeiJing2011]最小三角形(分治+几何)
bzoj2458: [BeiJing2011]最小三角形(分治+几何)
题目链接:bzoj2458: [BeiJing2011]最小三角形
学习推荐博客:分治法编程问题之最接近点对问题的算法分析
题解:先将所有点按x值排列,然后每次将当前区间[l,r]分成左右两半递归求解周长最小三角形。考虑到两半区间之间可能有连成最小三角形的情况,设dd为两半区间中最小三角形周长的最小值,筛选满足要求的点(x值与中点坐标x值的距离小于dd),然后按y值排序,进而暴搜出周长最小三角形。
1 #include<cstdio> 2 #include<cmath> 3 #include<queue> 4 #include<cstring> 5 #include<string> 6 #include<algorithm> 7 #define CLR(a,b) memset((a),(b),sizeof((a))) 8 using namespace std; 9 10 typedef long long ll;11 const double inf = 0x3f3f3f3f;12 const int N = 2e5+1;13 int n;14 struct Point{15 int x, y;16 }a[N], midp[N];17 double dis(Point a, Point b){18 return sqrt(1.*(a.x - b.x)*(a.x - b.x) + 1.*(a.y - b.y)*(a.y - b.y));19 }20 bool cmp1(Point a, Point b){21 return a.x < b.x;22 }23 bool cmp2(Point a, Point b){24 return a.y < b.y;25 }26 double solve(int l, int r){27 if(l == r ||l + 1 == r) return inf;28 if(l + 2 == r) return dis(a[l],a[l+1]) + dis(a[l+1],a[r]) + dis(a[l],a[r]);29 30 int m = l + (r-l)/2;31 double d1 = solve(l, m);32 double d2 = solve(m+1, r);33 double d = min(d1, d2);34 double dd = d/2.0;35 double ans = d;36 37 int cnt = 0, i, j, k;38 for(i = l; i <= r; ++i)39 if(fabs(a[m].x - a[i].x) <= dd)40 midp[++cnt] = a[i];41 sort(midp+1, midp+1+cnt, cmp2);42 43 for(i = 1; i < cnt-1; ++i){44 for(j = i+1; j < cnt; ++j){45 if(midp[j].y - midp[i].y > dd)46 break;47 for(k = j+1; k <= cnt; ++k){48 if(midp[k].y - midp[i].y > dd)49 break;50 double c = dis(midp[i],midp[j])+dis(midp[j],midp[k])+dis(midp[i],midp[k]);51 ans = min(ans, c);52 }53 }54 }55 return ans;56 }57 int main(){58 scanf("%d", &n);59 for(int i = 1; i <= n; ++i)60 scanf("%d%d", &a[i].x, &a[i].y);61 sort(a+1, a+1+n, cmp1);62 printf("%.6lf\n", solve(1,n));63 return 0;64 }
bzoj2458: [BeiJing2011]最小三角形(分治+几何)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。