LA 2572 - Viva Confetti

来源:互联网 发布:天然气库存数据影响 编辑:程序博客网 时间:2024/05/01 17:54

这道题是训练指南上面的例题,判断小圆弧的时候,求出一个圆跟其它所有圆的交点,然后判断两个相邻交点之间的中点。如果这个中点没有在这个圆上面的所有圆里面,那么这个交点就没有被挡住,也就是说这个圆可见。然后这个交点下面的第一个圆也是可见的。

做的时候看了一下别人的博客,然后自作聪明的把判断两个圆相交的函数改了。本来的函数里面是求圆C1跟C2的交点,求完焦点以后只把容器C1里面加入交点的极角,这样循环的时候就需要  

for(int i=0;i<n;++i){
      for(int t=0;t<n;++t){
           CircleCircleIntersection(i,t);
      }
    }

我想把它改成

for(int i=0;i<n;++i){
     for(int t=i+1;t<n;++t){
          CircleCircleIntersection(i,t);
      }
    }

这样在圆相交的函数里面一次就需要修改C1跟C2的容器。这样就一直错。开始没看出来什么函数错了,一直在找,后来发现是求C2的极角的时候出问题了,修改过来就对了。但是还是不能一次把两个圆的交点一起求。

找了好长时间错误,终于找到错那了。。我加的那些计算每错,错的地方是精确度。题目要求精确度是加减五乘十的负十三次方,我把eps设置成了十的负十三次放。把精确度改过来以后,怎么写怎么对。。

代码如下:

#include<iostream>#include<cmath>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int maxn=105;const double pi=cos(-1);struct Point{    double x,y;    Point(double x,double y):x(x),y(y){}};typedef Point Vector;Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}Vector operator * (Vector a,double p){return Vector(a.x*p,a.y*p);}Vector operator / (Vector a,double p){return Vector(a.x/p,a.y/p);}bool operator < (const Point& a,const Point& b){    return a.x<b.x||(a.x==b.x&&a.y<b.y);}const double eps=1e-14;int dcmp(double x){    if(fabs(x)<eps)return 0;    return x<0?-1:1;}bool operator == (const Point& a ,Point& b){    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}struct Circle{    Point c;    double r;    Circle(Point c=Point(0,0),double r=0):c(c),r(r){}    Point point(double a){        return Point(c.x+cos(a)*r, c.y+sin(a)*r);    }};double Dot(Vector a,Vector b){    return a.x*b.x+a.y*b.y;}double Length(Vector A){    return sqrt(Dot(A,A));}double Angle(Vector a,Vector b){//ÏòÁ¿¼Ð½Ç     return acos(Dot(a,b)/Length(a)/Length(b));}double angle(Vector a){//ÏòÁ¿µÄ¼«½Ç     return atan2(a.y,a.x);}int n;vector<double> pointAng[maxn];Circle C[maxn];int vis[maxn];bool PointInCircle(Point p,Circle C){    if(dcmp(Length(p-C.c)-C.r)<0)return 1;    return 0;}bool CircleInCircle(int c1,int c2){    Circle C1=C[c1];    Circle C2=C[c2];    double d=Length(C1.c-C2.c);    if(dcmp(d)==0){        if(dcmp(C1.r-C2.r)<=0)return 1;        return 0;    }    if(dcmp(C2.r-C1.r-d)>0)return 1;    return 0;}int CircleCircleIntersection(int c1,int c2){//    cout<<"c1="<<c1<<' '<<"c2="<<c2<<endl;    Circle C1=C[c1];    Circle C2=C[c2];    double d=Length(C1.c-C2.c);    if(dcmp(d)==0){        if(dcmp(C1.r-C2.r)==0)return -1;        return 0;    }    if(dcmp(C1.r+C2.r-d)<0)return 0;    if(dcmp(fabs(C1.r-C2.r)-d)>0)return 0;    double a=angle(C2.c-C1.c);    double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d));//    cout<<"///"<<C1.r<<' '<<C2.r<<' '<<d<<' '<<(C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d)<<endl;    Point p1 =C1.point(a-da),p2=C1.point(a+da);//    cout<<c1<<' '<<c2<<' '<<"C1 "<<C1.c.x<<' '<<C1.c.y<<' '<<C1.r<<' '<<C2.c.x<<' '<<C2.c.y<<' '<<C2.r<<" zz "<<p1.x<<' '<<p1.y<<' '<<p2.x<<' '<<p2.y<<"a="<<a<<' '<<"da="<<da<<endl;    if(p1==p2)return 1;    pointAng[c1].push_back(a-da);    pointAng[c1].push_back(a+da);//    double a2=pi+a;//    if(a2<-pi)a2+=(2*pi);//    if(a2>pi)a2-=(2*pi);//    da=Angle(p1-C2.c,C1.c-C2.c);    double pa1=angle(p1-C2.c);    double pa2=angle(p2-C2.c);    pointAng[c2].push_back(pa1);    pointAng[c2].push_back(pa2);//    a=angle(C1.c-C2.c);//    da=acos((C2.r*C2.r+d*d-C1.r*C1.r)/(2*C2.r*d));//    pointAng[c2].push_back(a-da);//    pointAng[c2].push_back(a+da);    return 2;} void solve(){    memset(vis,0,sizeof(vis));    for(int i=0;i<n;++i){        for(int t=i+1;t<n;++t){//            cout<<"i="<<i<<' '<<"t="<<t<<endl;            CircleCircleIntersection(t,i);        }    }    for(int i=0;i<n;++i){        if(!pointAng[i].size())continue;        sort(pointAng[i].begin(),pointAng[i].end());        vector<double>::iterator iter=unique(pointAng[i].begin(),pointAng[i].end());        pointAng[i].resize(iter-pointAng[i].begin());    }    for(int i=0;i<n;++i){        int ez=pointAng[i].size();        if(!ez){            bool can=1;            for(int t=i+1;t<n;++t){                if(CircleInCircle(i,t)){can=0;break;}            }            if(can)vis[i]=1;        }        else{            pointAng[i].push_back(pointAng[i][0]);            for(int j=0;j<pointAng[i].size();++j){                Point midpoint=C[i].point((pointAng[i][j]+pointAng[i][j+1])/2);                bool can=1;                for(int k=i+1;k<n;++k){                    if(PointInCircle(midpoint,C[k])){can=0;break;}                }    //            cout<<i<<' '<<j<<' '<<pointAng[i].size()<<' '<<midpoint.x<<' '<<midpoint.y<<' '<<(midpoint.x-C[i].c.x)*(midpoint.x-C[i].c.x)+(midpoint.y-C[i].c.y)*(midpoint.y-C[i].c.y)<<' '<<can<<endl;                if(can){                    vis[i]=1;                    for(int k=i-1;k>=0;--k){                        if(PointInCircle(midpoint,C[k])){//                            cout<<"tttttttttt"<<endl;                            vis[k]=1;break;}                    }                }            }                }    }    int ans=0;    for(int i=0;i<n;++i){        if(vis[i])ans++;    }    cout<<ans<<endl;}int main(){//    freopen("data.txt","r",stdin);    ios::sync_with_stdio(false);    while(cin>>n){        if(n==0)break;        for(int i=0;i<n;++i){            cin>>C[i].c.x>>C[i].c.y>>C[i].r;        }        solve();    }    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 工人档案丢了怎么办 事业单位试用期考核不合格怎么办 工厂不好招人怎么办 办理入职手续怎么办 管理员工不加班怎么办 没有毕业证怎么办入职 不想加班的员工怎么办 邮寄辞职信拒收怎么办 办理退休档案不见了怎么办 办理退休没有档案怎么办 办理退休没有个人档案怎么办 档案被学校丢失怎么办 手动挡汽车脱档怎么办 辞职工作没人交接怎么办 ipad反复重启怎么办 ipad老是重启怎么办 苹果8死机了怎么办 平板突然死机了怎么办 平板卡死机了怎么办 小米ipad死机了怎么办 ipad死机了黑屏怎么办 小米4死机了怎么办 小米平板黑屏是怎么办? ipad死机怎么办不能关机 ipad突然死机了怎么办 京东买ipad坏了怎么办 ipad开机键失灵怎么办 苹果手机按键坏了怎么办 ipad使用中黑屏怎么办 苹果下不可软件怎么办 大学毕业想要当演员怎么办 郑州东站怎么办临时身份证 因招工年龄大造小档桉怎么办 6楼层顶墙边漏水怎么办 信访三级终结后怎么办 领导安排工作不合理怎么办 老板不安排工作怎么办 孩子啃老父母怎么办 孩子变成讨好形怎么办 工厂破产了工资怎么办 失业就业登记证怎么办?