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\n", 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\n", 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\n", Ca, sum / (PI * d));
    }
}

HDU 4978 A simple probability problem

时间: 2024-08-09 02:20:05

HDU 4978 A simple probability problem的相关文章

HDU 4978 A simple probability problem 【凸包】【几何】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4978 题目大意:给你在平面上一些平行的线,线之间的距离是D,然后在给你一些不共线的点,每两点之间都有线相连,现在问这些点连成的线与平面上平行的线相交的概率. 这里要先介绍一个模型:蒲丰投针问题 知道了这个模型之后我们就能解决只有两个点的问题了,P=2L/πD (L为针长,D为平行线间距) 但是给出的是有很多个点,所以我们还要知道蒲丰投针问题扩展,将给出的点构造成一个凸包,若是凸包内部的线可以和平面上

HDU 4978 A simple probability problem.(概率模型+凸包周长)

题意:一个直径为d的圆中有n个点,每两点间有线段连接,一个平面上有间距都为d的平行线,求将原放在该平面上至少有一条线段与平行线相交的概率: 思路: 蒲丰针问题:http://wenku.baidu.com/link?url=s3rJRGUhCZ7kmsXA6o7Edr8h1rJJbibu2Ocs1Yf5BpsPwSkjkK9w-uVSV4d-cBGV36UA9bpxVfqLLA9qlPwbWkYbjkFzDaP_N5dtWHVT_mi 长度为L的针与间距为d的平行线相交的概率为P=2*L/(pi

hdu 4974 A simple water problem(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4974 Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or

HDU 4974 A simple water problem(贪心)

HDU 4974 A simple water problem 题目链接 签到题,很容易贪心得到答案是(sum + 1) / 2和ai最大值的最大值 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100005; typedef long long ll; int t, n; ll a, Max, sum; int main(

HDU - 4974 A simple water problem

Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or 1 for each competitor and add it to the total score

2014多校第十场1004 || HDU 4974 A simple water problem

题目链接 题意 : n支队伍,每场两个队伍表演,有可能两个队伍都得一分,也可能其中一个队伍一分,也可能都是0分,每个队伍将参加的场次得到的分数加起来,给你每个队伍最终得分,让你计算至少表演了几场. 思路 : ans = max(maxx,(sum+1)/2) :其实想想就可以,如果所有得分中最大值没有和的一半大,那就是队伍中一半一半对打,否则的话最大的那个就都包了. 1 #include <cstdio> 2 #include <cstring> 3 #include <st

hdu 1757 A Simple Math Problem (乘法矩阵)

A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2441    Accepted Submission(s): 1415 Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) =

HDU 4974 A simple water problem 模拟(水

水题. #include <cstdio> #include <iostream> #include <queue> #include <algorithm> using namespace std; typedef long long ll; priority_queue<int> q; int main() { int T, cas = 0; scanf("%d", &T); while(T-- > 0) {

矩阵十题【八】 HDU 1715 A Simple Math Problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757 题目大意: If x < 10   ,则  f(x) = x. If x >= 10 ,则  f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 * f(x-10); 给出k,m和a0~a9,求f(k)%m,  k<2*10^9 , m < 10^5 这是一个递推式,故可以用矩阵乘法来求 和上题类似,具体思路过程见上题