• 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
    ", solve(1,n));
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    记住我
    国米夺冠
    小谈“汉字转换成拼音(不带声调)”
    NLP资源共享盛宴
    文本分类资源和程序开源共享
    菜鸟进阶:C++实现Chisquare 特征词选择算法
    欢迎大家试用信息领域学科知识服务平台
    欢迎大家加入NLP,WEBIR,DATA Ming 的技术QQ群
    求两点之间所有路径的算法
    step by step 文本分类(一)
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/5917988.html
Copyright © 2020-2023  润新知