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 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 x1y1x2 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%

题意就是给出一个圆 , 还有一些线段( 不过圆心 )

问在圆上的点与圆心的连线没有交点的点占总点数的百分比。

那么就将所有线段的两个端点都弄成极角。然后排个序。

如果线段的两个端点极角分别跨越正负的话,就将它处理成两条线段 。

再处理一下区间 , 求百分比就能过了。

#include<bits/stdc++.h>
using namespace std;
const int N = 205;
const double PI = acos(-1.0);
const double eps = 1e-6;
typedef pair<double,double> pii;
#define X first
#define Y second
int n , top ;
vector<pii>p;
double x[N] , y[N];

int dcmp( double x ) {
    if( fabs(x) < eps ) return 0 ;
    return x<0?-1:1;
}

double cal( double avg1 , double avg2 ) {
    if( avg1 < 0 && avg2 < 0 ) return -1.0 ;
    if( avg1 > 0 && avg2 > 0 ) return -1.0 ;
    return fabs( avg1 ) + fabs( avg2 ) ;
}
void Solve() {
    top = 0 ;
    for( int i = 0 ; i < p.size() ; ++i ){
        while( top > 0 && dcmp( p[i].X-x[top-1])==0 && dcmp(p[i].Y-y[top-1])>=0 )top--;
        if( top > 0 && dcmp(x[top-1]-p[i].X)<=0 && dcmp(y[top-1]-p[i].Y)>=0 )continue ;
        x[top] = p[i].X , y[top] = p[i].Y , top++;
    }
}
void Run() {
    double x1 , y1 , x2 , y2 , r ;
    scanf("%d%lf",&n,&r); p.clear();
    if( !n ) { puts("100.00%"); return ; }
    for( int i = 0 ; i < n ; ++i ){
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        double avg1 = atan2(y1,x1) , avg2 = atan2(y2,x2) ;
        if( avg1 > avg2 ) swap( avg1 , avg2 );
        double d = cal( avg1 , avg2 );
        if( d == -1.0 ) { p.push_back(pii(avg1,avg2)); continue; }
        if( d < PI ) {
            p.push_back(pii(avg1,0));
            p.push_back(pii(0,avg2));
        }
        else {
            p.push_back(pii(-PI,avg1));
            p.push_back(pii(avg2,PI));
        }
    }
    sort( p.begin() , p.end() );
    Solve();
    double s = x[0] , e = y[0] , fenzi = 0 ;
    for( int i = 1 ; i < top ; ++i ){
        if( x[i] > e ) {
            fenzi += ( e - s ); s = x[i];
        }
        e = y[i] ;
    }
    fenzi += ( e - s );
    double ans = 100.0 - fenzi/(2.0*PI)*100.0;
    printf("%.2lf",ans);puts("%");
}

int main() {
//    freopen("in.txt","r",stdin);
    int _ , cas = 1 ;
    scanf("%d",&_); while( _ -- ) {
        printf("Case %d: ",cas++);
        Run();
    }
}

时间: 2024-10-08 12:03:11

UVA 11355 Cool Points( 极角计算 )的相关文章

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

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

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

UVA 10700 Camel trading(计算式子加减乘除的优先级处理)

Camel trading Time Limit: 1 second Background Aroud 800 A.D., El Mamum, Calif of Baghdad was presented the formula 1+2*3*4+5, which had its origin in the financial accounts of a camel transaction. The formula lacked parenthesis and was ambiguous. So,

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(

poj 1279 Art Gallery(利用极角计算半平面交)

题意:给出n个点的坐标描述一个多边形画廊.在画廊平面上找到一片表面,从该区域能够看到画廊墙壁上的每一个点: 思路:将这片表面称为多边形的核.核中一点与多边形边界上任意一点的连线都在多边形内部.凸多边形的核为其本身,凹多边形的核为其内部的一部分或不存在: 将多边形的n个顶点转化为n条边的直线方程:逆时针用多边形的边剖分多边形所在平面,保留向里的部分,舍去向外的部分,剩下的即为核: 利用叉积公式计算核面积,即为所求面积: #include<cstdio> #include<cstring&g

poj 2540 Hotter Colder(极角计算半平面交)

题意:玩家A初始时在(0,0)位置,每移动一次,玩家B提示与目标位置的距离远了.近了还是不变:在B回答后,确定目标位置可能存在的区域面积: 思路:以玩家A上一个位置与当前位置的连线做中垂线,将目标位置代入中垂线方程,得到对应不等式,根据回答的类型增加相应的半平面: 每回合后对当前半平面求交,输出交的面积: #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #incl

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