Files
OI-source/2.1308.cpp
2023-08-03 09:22:52 +08:00

128 lines
2.6 KiB
C++

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
struct Point
{
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
};
typedef Point Vector;
inline Point read_point()
{
Point A;
scanf("%lf%lf",&A.x,&A.y);
return A;
}
inline Vector operator+(const Vector &A,const Vector &B)
{ return Vector(A.x+B.x,A.y+B.y); }
inline Vector operator-(const Point &a,const Point &b)
{ return Vector(a.x-b.x,a.y-b.y); }
inline Vector operator*(const Vector &A,double p)
{ return Vector(A.x*p,A.y*p); }
inline Vector operator/(const Vector &A,double p)
{ return Vector(A.x/p,A.y/p); }
inline bool operator<(const Point &a,const Point &b)
{ return a.x<b.x||(a.x==b.x&&a.y<b.y); }
const double Pi=acos(-1);
const double eps=5e-13;
inline int dcmp(double x)
{ return (x>0?x:-x)<eps?0:(x>0?1:-1); }
inline bool operator==(const Point &a,const Point &b)
{ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; }
inline double Dot(const Vector &A,const Vector &B)
{ return A.x*B.x+A.y*B.y; }
inline double Length(const Vector &A)
{ return sqrt(Dot(A,A)); }
inline double Angle(const Vector &A)
{ return atan2(A.y,A.x); }
struct Circle
{
Point c;
double r;
Circle(Point c=Point(),double r=0):c(c),r(r){}
inline Point point(double a,double delta)
{ return Point(c.x+cos(a)*(r+delta),c.y+sin(a)*(r+delta)); }
};
inline Circle read_circle()
{
Circle C;
scanf("%lf%lf%lf",&C.c.x,&C.c.y,&C.r);
return C;
}
using namespace std;
int n;
Circle c[105];
bool cansee[105],flag;
inline bool in(const Point &p,const Circle &c)
{ return dcmp(Length(c.c-p)-c.r)<=0; }
vector<double> ang;
void intersectangle(int i,int j)
{
double d=Length(c[i].c-c[j].c);
if (dcmp(d-fabs(c[i].r-c[j].r))<=0
||dcmp(d-c[i].r-c[j].r)>=0) return;
double x=Angle(c[j].c-c[i].c),
y=acos((c[i].r*c[i].r+d*d-c[j].r*c[j].r)/2/c[i].r/d);
ang.push_back(x+y);
ang.push_back(x-y);
}
void mark(const Point &p)
{
for(int i=n-1;i>=0;i--)
if(in(p,c[i]))
{
cansee[i]=true;
return;
}
}
int main()
{
#ifdef local
freopen("pro.in","r",stdin);
#endif
while(scanf("%d",&n)==1&&n)
{
for(int i=0;i<n;i++) c[i]=read_circle();
memset(cansee,0,sizeof(cansee));
for(int i=0;i<n;i++)
{
ang.clear();
for(int j=0;j<n;j++)
if(i!=j)
intersectangle(i,j);
if(ang.empty())
{
mark(c[i].point(0,eps));
mark(c[i].point(0,-eps));
continue;
}
sort(ang.begin(),ang.end());
for(int j=0;j<ang.size();j++)
{
double x=(ang[j]+ang[(j+1)%n])/2;
mark(c[i].point(x,eps));
mark(c[i].point(x,-eps));
}
}
int res=0;
for(int i=0;i<n;i++) res+=cansee[i];
printf("%d\n",res);
}
return 0;
}