ZOJ 1696 Viva Confetti 计算几何
計算幾何:按順序給n個圓覆蓋。問最后能夠有幾個圓被看見。。
。
對每一個圓求和其它圓的交點,每兩個交點之間就是可能被看到的圓弧,取圓弧的中點,往外擴展一點或者往里縮一點,從上往下推斷有沒有圓能夠蓋住這個點,能蓋住這個點的最上面的圓一定是可見的
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
-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\n",ans); } return 0; }
總結
以上是生活随笔為你收集整理的ZOJ 1696 Viva Confetti 计算几何的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式:常见模式案例
- 下一篇: 《快学Scala》第二章 控制结构和函数