HDU 4978 A simple probability problem.(思维+凸包)

博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/38827629

 

A simple probability problem.

 

多校第十场的一道几何,做了好久了,忘了发出来。比赛的时候由于坑爹的模板,后台100组数据错了一组,导致比赛的时候没做出来,赛后郁闷了好久。。。。。比赛之后好好整了一下凸包的模板,代码里会是Graham算法,标程用的是Andrew算法。

 

题目大意:一个无限大的平面上,有间距为D的无限条水平直线,如图所示。

给你一个直径为D的硬币,硬币中有n个点,每两个点之间都有一条线段,任意三点不会共线。随机的将硬币扔到上图中的平面内,问至少有一条线段跟平面内的直线相交的概率是多少。

 

解题思路:很容易想到的是,对于硬币上的所有点来说,无疑是构成一个凸包的时候为所求的情况,而当点的个数为1的时候,概率为0。

 

 

  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 using namespace std;
  6 const double eps = 1e-6;
  7 const double Pi = acos(-1.0);
  8 #define zero(x) (((x) > 0 ? (x) : (-x)) < eps)
  9 
 10 int q, n;
 11 
 12 struct Point
 13 {
 14     double x,y;
 15     Point() {}  Point(double _x,double _y)
 16     {
 17         x = _x;
 18         y = _y;
 19     }  Point operator -(const Point &b)const
 20     {
 21         return Point(x - b.x,y - b.y);
 22     }  //叉积
 23     double operator ^(const Point &b)const
 24     {
 25         return x*b.y - y*b.x;     //点积
 26     }
 27     double operator *(const Point &b)const
 28     {
 29         return x*b.x + y*b.y;     //绕原点旋转角度B(弧度值),后x,y的变化
 30     }
 31     void transXY(double B)
 32     {
 33         double tx = x,ty = y;
 34         x = tx*cos(B) - ty*sin(B);
 35         y = tx*sin(B) + ty*cos(B);
 36     }
 37 } P[105], ch[105];
 38 
 39 double Distance(Point a, Point b){
 40     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 41 }
 42 double xmult(Point p1, Point p2, Point p){
 43     return (p1.x-p.x)*(p2.y-p.y) - (p1.y-p.y)*(p2.x-p.x);
 44 }
 45 int dcmp(double x){
 46     return fabs(x)<eps?0:(x<0?-1:1);
 47 }
 48 bool cmp(Point a, Point b){
 49     if(dcmp(xmult(a, b, P[0])) == 0){
 50         return Distance(a, P[0]) < Distance(b, P[0]);
 51     }
 52     else {
 53         return dcmp(xmult(a, b, P[0])) > 0;
 54     }
 55 }
 56 int Graham(int n){
 57     int s = 0, top = 1;
 58     for(int i = 0; i < n; ++i){
 59         if(P[i].y < P[s].y || (P[i].y == P[s].y && P[i].x < P[s].x)){
 60             s = i;
 61         }
 62     }
 63     if(s != 0){
 64         Point tmp = P[0];
 65         P[0] = P[s];
 66         P[s] = tmp;
 67     }
 68     sort(P+1, P+n, cmp);
 69     ch[0] = P[0], ch[1] = P[1];
 70     for(int i = 2; i < n; ++i){
 71         while(top > 0 && dcmp(xmult(ch[top], P[i], ch[top-1])) < 0){
 72             top--;
 73         }
 74         ch[++top] = P[i];
 75     }
 76     return top+1;
 77 }
 78 
 79 
 80 int T;
 81 double d;
 82 
 83 int main()
 84 {
 85     //freopen("1008.in", "r", stdin);
 86     //freopen("data.out", "w", stdout);
 87     int icase = 1;
 88     scanf("%d", &T);
 89     while(T--){
 90         scanf("%d%lf", &n, &d);
 91         for(int i = 0; i < n; ++i){
 92             scanf("%lf%lf", &P[i].x, &P[i].y);
 93         }
 94         printf("Case #%d: ", icase++);
 95         if(n >= 3){
 96             int t = Graham(n);
 97             //printf("%d\n", t);
 98             double sum = Distance(ch[0], ch[t-1]);
 99             for(int i = 0; i < t-1; ++i){
100                 sum += Distance(ch[i], ch[i+1]);
101             }
102             //printf("q = %d\n", q);
103             //printf("%lf\n", Area());
104             //printf("%lf\n" ,sum);
105             printf("%.4lf\n", sum/(Pi*(d)));
106         }
107         else if(n == 2){
108             double dis = Distance(P[0], P[1]);
109             printf("%.4lf\n", 2*dis/(Pi*d));
110         }
111         else {
112             printf("0.0000\n");
113         }
114         //printf("%lf %lf\n", Min.y, Max.y);
115     }
116 
117     return 0;
118 }
119 
120 /*
121 100
122 3 3
123 0 1
124 1 0
125 -1 0
126 */
Graham算法

 

posted @ 2014-08-25 21:46  GLSilence  阅读(304)  评论(0编辑  收藏  举报