zoukankan      html  css  js  c++  java
  • 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
    ",cas,ans);
    141     }
    142     return 0;
    143 }
  • 相关阅读:
    cocos2d3.8.1 使用prebuild提升发布android速度
    AS3条件编译
    Box2d FilterData
    旋转关节(Revolute Joint)
    线关节(Line Joint)
    平移关节(Prismatic Joint)
    滑轮关节(b2PulleyJoint)
    PAT Basic 1043 输出PATest (20 分)
    PAT Basic 1042 字符统计 (20 分)
    PAT Basic 1039 到底买不买 (20 分)
  • 原文地址:https://www.cnblogs.com/little-w/p/3573370.html
Copyright © 2011-2022 走看看