UVA 11355 Cool Points

Cool Points

We have a circle of radius R and several line segments situated within the circumference of this circle. Let’s define a cool point to be a point on the circumference of this circle so that the line segment that is formed by this point and the centre of the circle makes no intersection with any of the given line segments.

For this problem, you have to find out the percentage of cool points from all possible points on the circumference of the given circle.

Input

The input file starts with an integer T(T<1000) that indicates the number of test cases. Each case starts with 2 integers N(0 <= N < 100) and R(0 < R < 1001). N represents the number of line segments and R represents the radius of the circle. Each of the next N lines contains 4 integers in the order x1, y1,x2 and y2. (x1, y1)(x2, y2) represents a line segment.

You can assume that all the line segments will be inside the circle and no line segment passes through the origin. Also consider the center of the circle to be on the origin.

Output

For each input, output the case number followed by the percentage, rounded to 2 decimal places, of cool points. Look at the output for exact format.

Sample Input

Output for Sample Input

2

1 10

2 0 0 2

0 5

Case 1: 75.00%

Case 2: 100.00%

view code#include <bits/stdc++.h>

using namespace std;
double PI = acos(-1.0);
int _, cas=1, n, r;

struct event
{
    double x;
    int y;
    bool operator < (const event &o) const{
        return x<o.x;
    }
    event() {}
    event(double x, int y):x(x),y(y) {}
}e[4321];
int ecnt;

void addseg(double a, double b)
{
    if(a>b) swap(a,b);
    e[ecnt++] = event(a, 1);
    e[ecnt++] = event(b, -1);
}

int main()
{
//    freopen("in.txt", "r", stdin);
    cin>>_;
    while(_--)
    {
        scanf("%d%d", &n, &r);
        ecnt = 0;
        double a,b,c,d;
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
            double x = atan2(b,a), y = atan2(d,c);
            if(x<y) swap(x, y);
            if(x-y>PI)
            {
                addseg(-PI, y);
                addseg(x, PI);
            }
            else addseg(x, y);
        }
        int eventnum = 0;
        sort(e, e+ecnt);
        double last = -PI, ans = 0.0;
        for(int i=0; i<ecnt; i++)
        {
            if(eventnum==0)//这里很经典,记下
            {
                ans += e[i].x - last;
            }
            eventnum += e[i].y;
            last = e[i].x;
        }
        ans += PI - last;
        printf("Case %d: %.2f%%\n", cas++, (ans/(PI*2)*100));
    }
    return 0;
}

UVA 11355 Cool Points

时间: 2024-10-06 18:00:31

UVA 11355 Cool Points的相关文章

UVA 11355 Cool Points( 极角计算 )

We have a circle of radius R and several line segments situated within the circumference of this circle. Let’s define a cool point to be a point on the circumference of this circle so that the line segment that is formed by this point and the centre

UVA 10869 - Brownie Points II(树状数组)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线,然后另一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1,3象限,第二个人为二四象限,问第一个个人按最优取法,能得到最小分数的最大值,和这个值下另一个人的得分可能情况 思路:树状数组,可以枚举一点,如果能求出右上和左下点的个数就好办了,其实用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后查询

UVA 12714 Two Points Revisited(简单数学题)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4452 题意: 给出两个点组成一条直线,要你任意输出两个点,要求这两点组成的直线和给出的直线垂直(注意输出的点不能有负数): 代码如下: #include <cstdio> int main(

UVA 10869 - Brownie Points II(树阵)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1.3象限,第二个人为二四象限.问第一个个人按最优取法,能得到最小分数的最大值,和这个值下还有一个人的得分可能情况 思路:树状数组,能够枚举一点,假设能求出右上和左下点的个数就好办了,其有用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后

uva 11355(极角计算)

传送门:Cool Points 题意:给一个圆心为原点的圆和一些线段,问所有线段两端点与圆心连线构成的角度总和占总360度的百分比. 分析:首先将所有线段的两端点变成极角,然后排序(范围[-PI,PI],即从x轴负方向逆时针转一圈),如果某一线段极角值之差大于PI,构成的角度值肯定不是<AOB,而是<AOX+XOB.因此处理好这种情况,从x轴负向走一圈计值即可. #include <algorithm> #include <cstdio> #include <cs

UVa 10295 - Hay Points

题目:有非常多工人.相应一个能力描写叙述表,每种能力有一个权值,求每一个工人的能力值. 分析:字符串.hash表,字典树.利用散列表或者字典树存储相应的单词和权值.查询就可以. 说明:注意初始化,计算完将数据清除. #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; //hash_define typedef stru

UVA 10869 - Brownie Points II(树状数组+离散化)

题目链接:点击打开链接 思路:统计区间和, 我们想到了树状数组, 离散化后, 枚举第一个人选取的x坐标, 用两个树状数组,以y坐标为下标建树, 一个表示当前左边的情况, 一个表示右边的情况, 再枚举当前垂直线上的每个点, 可以用树状数组快速统计结果, 该题题意挺难理解的, 要求输出第一个人的最小得分的最大值ans, 还有就是当第一个人取ans时第二个人的可能得分.时间复杂度O(nlogn) 细节参见代码: #include <cstdio> #include <cstring> #

uva 10790 How Many Points of Intersection?

10790 How Many Points of Intersection? We have two rows. There are a dots on the top row and b dots on the bottom row. We draw line segments connecting every dot on the top row with every dot on the bottom row. The dots are arranged in such a way tha

8 UVA 10790 How Many Points of Intersection?

第一排第i个点和第二排第j个点相连,在这条线段上会产生(a-i)*(j-1)个交点, 以此类推,推公式即可. #include<cstdio> #define ll long long ll a,b; int cas=1; int main() { while(~scanf("%d%d",&a,&b)&&(a||b)) printf("Case %d: %lld\n",cas++,a*(a-1)/2*b*(b-1)/2);