hdu 4197 Popping Balloons

来源:互联网 发布:海拉尔二中分尸案 知乎 编辑:程序博客网 时间:2024/05/18 04:01

题意:输入n个圆,所有圆不覆盖原点,从原点至少发出多少条射线能穿过所有圆。(0<=n<=1000)

解法:讲每个圆转化为角度区间 [ s , e ] ,区间范围 [ 0 ,  2*Pi ) ,得到n段区间后按e值增序将区间排序,枚举起点进行贪心。

复杂度:O(n*n)

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>using namespace std;const double EP=1e-8;const double Pi=acos(-1.0);int n;struct Point{    double x, y, r, loc, s, e;}p[1005];bool cmp(Point p1, Point p2){    return p1.e<p2.e;}bool inside(double t1, double st, double end){    if(st<end) return t1>=st&&t1<=end;    else return t1>=st||t1<=end;}int main(){    //freopen("1.txt", "r", stdin);    int T, i, j, k, ans, cnt;    double t, d;    scanf("%d", &T);    while(T--){        scanf("%d", &n);        ans=n;        for(i=0; i<n; i++){            scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].r);            d=sqrt(p[i].x*p[i].x+p[i].y*p[i].y);            t=asin(p[i].r/d);            if(fabs(p[i].x)<EP){                if(p[i].y>0)p[i].loc=Pi*0.5;                else p[i].loc=Pi*1.5;            }            else {                p[i].loc=atan(fabs(p[i].y/p[i].x));                if(p[i].x<0&&p[i].y>=0)p[i].loc=Pi-p[i].loc;                else if(p[i].x>0&&p[i].y<0)p[i].loc=2*Pi-p[i].loc;                else if(p[i].x<0&&p[i].y<0)p[i].loc+=Pi;            }            p[i].s=p[i].loc-t;            if(p[i].s<-EP)p[i].s+=2*Pi;            p[i].e=p[i].loc+t;            if(p[i].e>=2*Pi-EP)p[i].e-=2*Pi;        }        sort(p, p+n, cmp);        for(i=0; i<n; i++){            cnt=1;            double t2=p[i].e;            for(j=1; j<n; j++){                if(!inside(t2, p[(i+j)%n].s, p[(i+j)%n].e)){                    t2=p[(i+j)%n].e;                    cnt++;                }            }            if(cnt<ans)            ans=cnt;        }        printf("%d\n", ans);    }    return 0;}