zoukankan      html  css  js  c++  java
  • HDU 4978 A simple probability problem

    A simple probability problem

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 43    Accepted Submission(s): 14



    Problem Description
    Equally-spaced parallel lines lie on an infinite plane. The separation between adjacent lines is D (D>0). Now considering a circle of diameter D. N points lie on or in the circle. It is guaranteed that any three points are not collinear. Between any two points there's a needle. Find the possibility that, if the circle is randomly (with equal probability on any position and direction) thrown onto the same plane described above (with the equally-spaced parallel lines of separation d), at least one needle crosses a line.
     

    Input
    The first line contains a single integer T (1 <= T <= 100), the number of test cases.

    For each set of input data, the first line gives two integers, N and D (N<=100), as described above. You can consider the center of the circle is default as the origin. Lastly N lines is followed, each containing two real numbers that representing the coordinate of a point lying within the circle.
     

    Output
    Each output should occupy one line. Each line should start with "Case #i: ", followed by a real number round to four decimal places, the probability that at least one needle crosses one line.
     

    Sample Input
    2 2 2 -0.5 0 0.5 0 3 3 0 1 1 0 -1 0
     

    Sample Output
    Case #1: 0.3183 Case #2: 0.5123
     

    Source
    2014 Multi-University Training Contest 10


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


    题目大意  :一个无限大的平面上有无数条等距平行线,每两条间距为D,给一个直径为D的圆,有n个点分布在圆上或者圆内,点的输入是依照已圆心为原点的坐标系,规定随意三点不共线。随意两点间的线段记为一根针。如今问将该圆投到平面上至少有一根针和当中一条平行线相交的概率


    题目分析  :计算几何的问题,首先考虑仅仅有两点的情况即一根针。这就是一个布丰投针问题,公式为P=2L/πD (L为针长。D为平行线间距)。再考虑多个点,显然是个凸包问题,假设凸包边上的线能够与平行线相交,凸包内的线必定能够与平行线相交,由投针问题的推广我们能够得到公式P = C/πD (C为凸包周长),详见布丰投针及推广


    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #define N 200
    #define inf 1e-6
    #define PI 3.141592653
    typedef struct
    {
        double x;
        double y;
    }point;
    point points[N]; 
    point chs[N];    
    int sp; 
    
    //求凸包周长的模板
    double dis(point a, point b)
    {
        return sqrt((a.x - b.x) * (a.x - b.x) * 1.0 + (a.y - b.y) * (a.y - b.y));
    }
    
    
    double multi(point p0, point p1, point p2)
    {
        return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
    }
    int cmp(const void *p, const void *q)
    {
         point a = *(point *)p;
         point b = *(point *)q;
        double k = multi(points[0], a, b);
        if(k < -inf)
            return 1;
        else if(fabs(k) < inf && (dis(a, points[0]) - dis(b, points[0])) > inf) 
            return 1;
        else return -1;
    }
    void convex_hull(int n)
    {
        int k, d;
        double miny = points[0].y;
        int index = 0;
        for(int i = 1; i < n; i++) 
        {
            if(points[i].y < miny) 
            {
                miny = points[i].y;
                index = i;
            }
            else if(points[i].y == miny && points[i].x < points[index].x) 
                 index = i;
        }
        point temp;
        temp = points[index];
        points[index] = points[0];
        points[0] = temp;
        qsort(points+1, n-1, sizeof(points[0]), cmp);
        chs[0] = points[n-1];
        chs[1] = points[0];
        sp = 1;
        k = 1;
        while(k <= n-1)
        {
            double d = multi(chs[sp], chs[sp-1], points[k]);
            if(d <= 0)
            {
                 sp++;
                 chs[sp] = points[k];
                 k++;
            }
            else sp--;
        }
    }
    int main()
    {
        double sum, d;
        int T, n;
        scanf("%d",&T);
        for(int Ca = 1; Ca <= T; Ca++)
        {
            sum = 0;
            scanf("%d %lf", &n, &d);
            if(n == 0 || n == 1)
            {
                printf("Case #%d: 0.0000
    ", Ca);
                continue;
            }
            for(int i = 0; i < n; i++)
                scanf("%lf%lf", &points[i].x, &points[i].y);
            if(n == 2)
            {
                double len = dis(points[0],points[1]);
                printf("Case #%d: %.4f
    ", Ca, (2 * len) / (PI * d));
                continue;
            }
            convex_hull(n);
            for(int i = 1; i <= sp; i++) 
                sum += dis(chs[i-1], chs[i]);
            sum += dis(chs[0], chs[sp]);   //算出凸包周长
            printf("Case #%d: %.4f
    ", Ca, sum / (PI * d));
        }
    }
    



  • 相关阅读:
    python学习-dict
    python学习
    pycharm 2017版Mac激活码
    Day6_python基础知识<模块学习>
    having 子句
    数据库实例指定
    EXCEL里面单元格内容太多显示不全应该怎么弄。
    你没有权限在此位置保存文件_请与管理员联系的问题解决
    FQ软件
    C#高级编程(中文第七版)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5234393.html
Copyright © 2011-2022 走看看