UVA 11168凸包+距离公式

  1 /*UVA 11168计算几何
  2 凸包+数学思维
  3 在直线同一侧的点,带入直线方程后,正负性是一致的,这个是解题的关键
  4 所以运用点到直线的距离公式,可以O(1)计算出距离,枚举出最短距离即可
  5 这里比较容易犯错的是:1、点斜式竖线无意义(也可用精度处理掉)2、点到直线的距离公式
  6 */
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <string.h>
 10 #include <math.h>
 11 #include <ctype.h>
 12 #include <string>
 13 #include <iostream>
 14 #include <sstream>
 15 #include <vector>
 16 #include <queue>
 17 #include <stack>
 18 #include <map>
 19 #include <list>
 20 #include <set>
 21 #include <algorithm>
 22 #define INF 0x3f3f3f3f
 23 #define eps 1e-7
 24 #define eps2 1e-3
 25 #define zero(x) (((x)>0?(x):-(x))<eps)
 26 using namespace std;
 27 
 28 
 29 struct Point
 30 {
 31     double x,y;
 32     Point() {}
 33     Point(double xx,double yy)
 34     {
 35         x=xx;
 36         y=yy;
 37     }
 38     bool operator<(const Point& p) const{
 39         if (x==p.x) return y<p.y;
 40         else return x<p.x;
 41     }
 42 }P1[10505],P2[10505];
 43 
 44 typedef Point Vector;
 45 
 46 bool operator==(Point A,Point B)
 47 {
 48     if ((fabs(A.x-B.x)<eps) && (fabs(A.y-B.y)<eps)) return true;
 49     else return false;
 50 }
 51 Vector operator-(Point A,Point B)//表示A指向B
 52 {
 53     return Vector(A.x-B.x,A.y-B.y);
 54 }
 55 Vector operator*(Vector A,double k)
 56 {
 57     return Vector(A.x*k,A.y*k);
 58 }
 59 Vector operator+(Point A,Point B)//表示A指向B
 60 {
 61     return Vector(B.x+A.x,B.y+A.y);
 62 }
 63 double Cross(Vector A,Vector B)
 64 {
 65     return A.x*B.y-A.y*B.x;
 66 }
 67 double Area2(Point A,Point B,Point C)
 68 {
 69     return Cross(B-A,C-A);
 70 }
 71 //p是原先点的数组,n是个数,ch是凸包的点集
 72 //精度要求高是用dcmp比较
 73 //返回凸包点的个数
 74 int ConvexHull(Point *p, int n, Point* ch){        //求凸包
 75     sort(p, p + n);//先按照x,再按照y
 76     int m = 0;
 77     for(int i = 0; i < n; i++){
 78         while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) < 0) m--;
 79         ch[m++] = p[i];
 80     }
 81     int k = m;
 82     for(int i = n-2; i >= 0; i--){
 83         while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) < 0) m--;
 84         ch[m++] = p[i];
 85     }
 86     if(n > 1) m--;
 87     return m;
 88 }
 89 double ConvexPolygonArea(Point *p, int n){//凸包面积
 90     double area = 0;
 91     for(int i = 1; i < n-1; i++) area += Area2(p[0], p[i], p[i+1]);
 92     return area / 2;
 93 }
 94 
 95 double X,Y;
 96 int t,n,cnt;
 97 
 98 double getdis(int k)
 99 {
100 
101     double ans=0;
102     Point p1=P2[k];
103     Point p2=P2[(k+1)%cnt];
104     if(fabs(p1.x-p2.x)<eps)//垂直线特判
105     {
106         for(int i=0;i<n;i++)//注意是所有点
107         {
108             double x=P1[i].x;
109             ans+=fabs(x-(p1.x+p2.x)/2);//取中点,减少精度损失
110         }
111 
112     }else{//转化成y=kx+b方程
113         double xie=(p1.y-p2.y)/(p1.x-p2.x);
114         if(fabs(xie)<eps) xie=0;//调试中出现了负0
115         double b=p1.y-xie*p1.x;
116         double s=fabs(xie*X+b*n-Y),t=sqrt(xie*xie+1);
117         ans=s/(t+0.0);
118     }
119     return ans;
120 }
121 int main()
122 {
123 
124     cin>>t;
125 
126     for(int cas=1;cas<=t;cas++)
127     {
128         double ans=9999999999;
129         X=0,Y=0;
130         cin>>n;
131         for(int i=0;i<n;i++)
132         {
133             double x,y;cin>>x>>y;
134             P1[i]=Point(x,y);
135             X+=x,Y+=y;
136         }
137         cnt=ConvexHull(P1,n,P2);//凸包上的点
138         for(int i=0;i<cnt;i++)//枚举直线
139             ans=min(ans,getdis(i)/n);
140         printf("Case #%d: %.3lf\n",cas,ans);
141     }
142     return 0;
143 }

 

转载于:https://www.cnblogs.com/little-w/p/3573370.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值