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 }
View Code

 

posted @ 2016-09-28 21:14  GraceSkyer  阅读(703)  评论(0编辑  收藏  举报

~~~~~~ACM大牛语录,激励一下~~~~~~

为了世界的和平,为了女生的安全,我拼命做题,做题,做题!

用最短的时间,刷最多的题!

给我一滴泪,我就看到了你全部的海洋!

seize the hour, seize the day.

人生难免有无奈,幸福走远了,或是感叹幸福来迟了.其实我一直相信,无论手中的幸福是多么微不足道的感觉,我会把握住那每一分,每一秒,当幸福依旧像那百鸟般飞逝,终究无法掌握时,我会感谢它,曾经降临过!

A自己的题,让别人郁闷去吧

WA肠中过,AC心中留 TLE耳边过,AC特别牛

天然的悲苦和伤逝,过去有过,以后还会有

^*^一步一步往上爬^*^

AC就像练级,比赛就像PK. 练级不如PK好玩

其实,世上本没有ACM,AC的人多了,也便有了!

AC无止尽~ Seek you forever~

找呀找呀找水题,找到一个AC一个呀!

AC是检验程序的唯一标准。

真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血……