hdu 3007 Buried memory 最远点对

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3007

Each person had do something foolish along with his or her growth.But,when he or she did this that time,they could not predict that this thing is a mistake and they will want this thing would rather not happened.
The world king Sconbin is not the exception.One day,Sconbin was
sleeping,then swakened by one nightmare.It turned out that his love letters to
Dufein were made public in his dream.These foolish letters might ruin his
throne.Sconbin decided to destroy the letters by the military exercises‘s
opportunity.The missile is the best weapon.Considered the execution of the
missile,Sconbin chose to use one missile with the minimum
destruction.
Sconbin had writen N letters to Dufein, she buried these letters
on different places.Sconbin got the places by difficult,he wants to know where
is the best place launch the missile,and the smallest radius of the burst area.
Let‘s help Sconbin to get the award.

题意描述:给出n封信的二维坐标,找到一个坐标点,使其距离n封信的最远距离最近。

算法分析:最远点对的模板题。需要注意一点:题目中的坐标点没规律,最远点对的算法针对凸边形,所以首先我们得对题目点集凸包化。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<vector>
  8 #define inf 0x7fffffff
  9 #define exp 1e-10
 10 #define PI 3.141592654
 11 using namespace std;
 12 const int maxn=500+10;
 13
 14 int n;
 15 struct Point
 16 {
 17     double x,y;
 18     Point(double x=0,double y=0):x(x),y(y){}
 19 }an[maxn],bn[maxn];
 20 typedef Point Vector;
 21 double dcmp(double x)
 22 {
 23     if (fabs(x)<exp) return 0;
 24     return x<0 ? -1 : 1;
 25 }
 26 Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x , A.y+B.y); }
 27 Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x , A.y-B.y); }
 28 Vector operator * (Vector A,double p) {return Vector(A.x*p , A.y*p); }
 29 Vector operator / (Vector A,double p) {return Vector(A.x/p , A.y/p); }
 30 bool operator < (Point a,Point b) {return a.x<b.x || (a.x==b.x && a.y<b.y); }
 31 bool operator == (Point a,Point b) {return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
 32
 33 double Dot(Vector A,Vector B) {return A.x*B.x + A.y*B.y ; }
 34 double Length(Vector A,Vector B) {return sqrt(Dot(A,A)); }
 35 double cross(Vector A,Vector B) {return A.x*B.y - B.x*A.y; }
 36
 37 double dist(Point A,Point B)
 38 {
 39     double xx=(A.x-B.x)*(A.x-B.x);
 40     double yy=(A.y-B.y)*(A.y-B.y);
 41     return sqrt(xx+yy);
 42 }
 43
 44 Point cur;
 45 double rotating_calipers(Point *ch,int n)
 46 {
 47     int q=1;
 48     double ans=-1;
 49     cur.x=cur.y=0;
 50     ch[n]=ch[0];
 51     for (int p=0 ;p<n ;p++)
 52     {
 53         while (cross(ch[q+1]-ch[p+1],ch[p]-ch[p+1])>cross(ch[q]-ch[p+1],ch[p]-ch[p+1]))
 54             q=(q+1)%n;
 55         double len=dist(ch[p],ch[q]);
 56         double len2=dist(ch[p+1],ch[q+1]);
 57         if (len>ans+exp)
 58         {
 59             ans=len;
 60             cur.x=(ch[p].x+ch[q].x)/2.0;
 61             cur.y=(ch[p].y+ch[q].y)/2.0;
 62         }
 63         if (len2>ans+exp)
 64         {
 65             ans=len2;
 66             cur.x=(ch[p+1].x+ch[q+1].x)/2.0;
 67             cur.y=(ch[p+1].y+ch[q+1].y)/2.0;
 68         }
 69     }
 70     return ans;
 71 }
 72
 73 int Convexhull(Point *p,int n,Point *ch)
 74 {
 75     sort(p,p+n);
 76     int m=0;
 77     for (int i=0 ;i<n ;i++)
 78     {
 79         while (m>1 && dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<0) m--;
 80         ch[m++]=p[i];
 81     }
 82     int k=m;
 83     for (int i=n-2 ;i>=0 ;i--)
 84     {
 85         while (m>k && dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<0) m--;
 86         ch[m++]=p[i];
 87     }
 88     if (n>1) m--;
 89     return m;
 90 }
 91
 92 int main()
 93 {
 94     while (scanf("%d",&n)!=EOF && n)
 95     {
 96         for (int i=0 ;i<n ;i++) scanf("%lf%lf",&an[i].x,&an[i].y);
 97         if (n==1) {printf("%.2lf %.2lf 0.00\n",an[0].x,an[0].y);continue; }
 98         if (n==2) {printf("%.2lf %.2lf %.2lf\n",(an[0].x+an[1].x)/2.0,
 99             (an[0].y+an[1].y)/2.0,dist(an[0],an[1])/2.0);continue; }
100         int m=Convexhull(an,n,bn);
101         double ans=rotating_calipers(bn,m);
102         printf("%.2lf %.2lf %.2lf\n",cur.x,cur.y,ans/2.0);
103     }
104     return 0;
105 }
时间: 2024-12-16 03:14:57

hdu 3007 Buried memory 最远点对的相关文章

HDU 3007 Buried memory 最小圆覆盖

题目大意:没看.反正就是求最小圆覆盖. 思路:一个神奇的算法--随机增量法.可以证明,这个算法可以在O(n)的时间复杂度内求出最小圆覆盖.虽然好像能卡掉的样子,但是加上一句random_shuffle就卡不掉了. 具体的过程是这样的: 在全局记录一个圆,表示目前的最小圆覆盖.从头开始扫描.遇到第一个不在当前最小圆覆盖内的点的时候: 将这个点与当前最小圆覆盖的圆心为直径做一个圆,作为当前的最小圆覆盖.从头开始扫描.遇到第一个不在当前最小圆覆盖的点的时候: 将刚才的两个点和当前点做三角形,将这个三角

HDOJ 3007 Buried memory 增量法最小圆覆盖

增量法最小圆覆盖,简单模版 Buried memory Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2541    Accepted Submission(s): 1365 Problem Description Each person had do something foolish along with his or her g

【HDOJ】3007 Buried memory

1. 题目描述有n个点,求能覆盖这n个点的半径最小的圆的圆心及半径. 2. 基本思路算法模板http://soft.cs.tsinghua.edu.cn/blog/?q=node/1066定义Di表示相对于P[1]和P[i]组成的最小覆盖圆,如果P[2..i-1]都在这个圆内,那么当前的圆心和半径即为最优解.如果P[j]不在这个圆内,那么P[j]一定在新的最小覆盖圆的边界上即P[1].P[j].P[i]组成的圆.因为三点可以确定一个圆,因此只需要不断的找到不满足的P[j],进而更新最优解即可.其

HDU 3007

基本小圆覆盖模板题 #include <iostream> #include <algorithm> #include <cmath> using namespace std; int X,Y; int n; const double eps=0.00000001; struct point{ double x,y; }p[550]; struct Circle{ point cent; double r; }cir; double dist(point x, poin

HDU 3007 模拟退火算法

Buried memory Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4067    Accepted Submission(s): 2171 Problem Description Each person had do something foolish along with his or her growth.But,when

最小圆覆盖 hdu 3007

今天学习了一下最小圆覆盖, 看了一下午都没看懂, 晚上慢慢的摸索这代码,接合着别人的讲解, 画着图跟着代码一步一步的走着,竟然有些理解了. 最小圆覆盖: 给定n个点, 求出半径最小的圆可以把这些点全部包围, 可以在圆的边界上 下面是我的个人理解. 如果不对, 还请路过大牛指出 先找一个点, 让圆心等于这个点的坐标, 半径等于0, 显然这个对的, 接着找下一个点, 如果只有两个点的话, 那么最小的圆一定是以他们为直径做圆, 接着找第三个点, 如果第三个点在园内或者在边界上, 那么不用更新当前的最小

ZOJ 1450 HDU 3007 (最小圆覆盖)

首先这个圆边上必有至少两点,打乱数组,然后利用枚举,不断重新定义圆,找出最小的圆 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 100005; const double eps = 1e-8; int n; struct Point { double x, y; Point()

hdu 3007【最小圆覆盖-随机增量法】

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N=505; int n; double r; struct dian { double x,y; dian(double X=0,double Y=0) { x=X,y=Y; } dian operator + (const dian &a) c

计算几何题目分类

转载 一.基础题目 1.1 有固定算法的题目 A, 最近点对问题最近点对问题的算法基于扫描线算法.ZOJ 2107    Quoit Design    典型最近点对问题POJ    3714    Raid    变种最近点对问题 B,最小包围圆最小包围圆的算法是一种增量算法,期望是O(n).ZOJ    1450    Minimal Circle  HDU    3007    Buried memory C,旋转卡壳POJ 3608    Bridge Across Islands