zoukankan      html  css  js  c++  java
  • ZOJ 1696 Viva Confetti 计算几何


    计算几何:按顺序给n个圆覆盖。问最后能够有几个圆被看见。。

    对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这个点,能盖住这个点的最上面的圆一定是可见的


    Viva Confetti

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    Do you know confetti?

    They are small discs of colored paper, and people throw them around during parties or festivals. Since people throw lots of confetti, they may end up stacked one on another, so there may be hidden ones underneath.

    A handful of various sized confetti have been dropped on a table. Given their positions and sizes, can you tell us how many of them you can see?

    The following figure represents the disc configuration for the first sample input, where the bottom disc is still visible.


    Input

    The input is composed of a number of configurations of the following form.

    n
    x1 y1 r1
    x2 y2 r2
    . . .
    xn yn rn

    The first line in a configuration is the number of discs in the configuration (a positive integer not more than 100), followed by one line descriptions of each disc: coordinates of its center and radius, expressed as real numbers in the decimal notation, with up to 12 digits after the decimal point. The imprecision margin is 5*10^-13. That is, it is guaranteed that variations of less than 5*10^-13 on input values do not change which discs are visible. Coordinates of all points contained in discs are between -10 and 10.

    Confetti are listed in their stacking order, x1 y1 r1 being the bottom one and xn yn rn the top one. You are observing from the top.

    The end of the input is marked by a zero on a single line.


    Output

    For each configuration you should output the number of visible confetti on a single line.


    Sample Input

    3
    0 0 0.5
    -0.9 0 1.00000000001
    0.9 9 1.00000000001
    5
    0 1 0.5
    1 1 1.00000000001
    0 2 1.00000000001
    -1 1 1.00000000001
    0 -0.00001 1.00000000001
    5
    0 1 0.5
    1 1 1.00000000001
    0 2 1.00000000001
    -1 1 1.00000000001
    0 0 1.00000000001
    2
    0 0 1.0000001
    0 0 1
    2
    0 0 1
    0.00000001 0 1
    0


    Sample Output

    3
    5
    4
    2
    2


    Source: Asia 2002, Kanazawa (Japan)
    Submit    Status


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    const double eps=5*(1e-13);
    const double pi=acos(-1.0);
    
    int n;
    
    struct Point
    {
      double x,y;
      Point(){}
      Point(double _x,double _y):x(_x),y(_y){}
    };
    
    struct Circle
    {
      Point c;
      double r;
      Circle(){}
      Circle(Point _c,double _r):c(_c),r(_r){}
      Point point(double x) {return Point(c.x+cos(x)*r,c.y+sin(x)*r);}
    };
    
    double normal(double x)
    {
      return x-floor(x/(2*pi))*2*pi;
    }
    
    double dcmp(double x)
    {
      if(fabs(x)<=eps) return 0;
      return (x<0)?

    -1:1; } double DIST(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } Circle C[200]; double a[1000]; int tot=0; bool flag[110]; void check(Point x) { for(int i=n-1;i>=0;i--) { double d=DIST(x,C[i].c); if(dcmp(d-C[i].r)<0) { flag[i]=true; break; } } } int main() { while(scanf("%d",&n)!=EOF&&n) { memset(flag,0,sizeof(flag)); for(int i=0;i<n;i++) { double x,y,z; scanf("%lf%lf%lf",&x,&y,&z); C[i]=Circle(Point(x,y),z); } for(int i=0;i<n;i++) { tot=0; for(int j=0;j<n;j++) { if(i==j) continue; double dist=DIST(C[i].c,C[j].c); double ri=C[i].r,rj=C[j].r; if(dcmp(dist-ri-rj)>=0||dcmp(dist-fabs(ri-rj))<=0) continue; double t=atan2(C[j].c.y-C[i].c.y,C[j].c.x-C[i].c.x); double dt= acos((ri*ri+dist*dist-rj*rj)/(2.*ri*dist)); a[tot++]=normal(t+dt); a[tot++]=normal(t-dt); } a[tot++]=0;a[tot++]=2*pi; sort(a,a+tot); tot=unique(a,a+tot)-a; for(int j=0;j<tot-1;j++) { double u=(a[j]+a[j+1])/2; double r1=C[i].r+eps,r2=C[i].r-eps; Point p1=Point(C[i].c.x+r1*cos(u),C[i].c.y+r1*sin(u)); Point p2=Point(C[i].c.x+r2*cos(u),C[i].c.y+r2*sin(u)); check(p1); check(p2); } } int ans=0; for(int i=0;i<n;i++) if(flag[i]) ans++; printf("%d ",ans); } return 0; }




  • 相关阅读:
    观察者设计模式
    JSP中用jsp:param传递中文参数出现乱码
    使用.msi进行安装mysql程序(超详细)
    扒来的lstdc++.6.0.9有效解决方案
    HTML响应状态码
    砸壳
    ipv6
    犀利的文章
    安装ReactNative开发IDE
    创建ReactNative的iOS项目
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7055084.html
Copyright © 2011-2022 走看看