记录编号 378616 评测结果 AAAAAAAAAA
题目名称 [HAOI 2008]下落的圆盘 最终得分 100
用户昵称 Gravatar天一阁 是否通过 通过
代码语言 C++ 运行时间 0.313 s
提交时间 2017-03-04 11:50:45 内存使用 0.37 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>

#define LD double
#define sqr(x) ((x)*(x))
#define eps 1e-8
#define INF 1e50
#define N 1010
#define PI acos(-1)

using namespace std;

/*
+:向量+ 
-:向量-
*:向量的数乘 ,点积
^: 向量的叉积 
*/

struct node
{
    LD x,y;
    void scan()
	{
		scanf("%lf%lf",&x,&y);
	}
    void print()
	{
		printf("(%lf,%lf)\n",x,y);
	}
    node operator+(const node &a)const
	{
		return (node){x+a.x,y+a.y};
	} 
    node operator-(const node &a)const
	{
		return (node){x-a.x,y-a.y};
	}
    node operator*(const LD &a)const
	{
		return (node){x*a,y*a};
	}
    node operator/(const LD &a)const
	{
		return (node){x/a,y/a};
	}
    LD operator^(const node &a)
	{
		return x*a.y-y*a.x;
	}
    LD operator*(const node &a)
	{
		return x*a.x+y*a.y;
	}
    void operator+=(const node &a)
	{
		*this=*this+a;
	}
    void operator-=(const node &a)
	{
		*this=*this-a;
	}
    void operator*=(const LD &a)
	{
		*this=(*this)*a;
	}
    void operator/=(const LD &a)
	{
		*this=*this/a;
	}
    LD len() 
	{
		return (LD)sqrt(sqr(x)+sqr(y));
	}
	bool operator==(const node &a)const
	{
		return x==a.x && y==a.y;
	}
    bool operator<(const node &a)const
	{ 
        if(x==a.x) return y<a.y;
        return x<a.x;
    }
};

LD dist(node a,node b)
{
    return (a-b).len();
}

struct line
{
    node a,b;
    LD len()
	{
		return (a-b).len();
	}
    void scan()
	{
        a.scan();
        b.scan();
    }
    void print()
	{ 
        puts("the Line is");
        a.print();
        b.print();
    }
};

node unit(node x)
{
    LD tmp=x.len();
    x/=tmp;
    return x;
}

struct circle
{
	node o;
	LD r;
	void print()
	{
		o.print();
		printf("r = %.3lf\n",r);
	}
}a[N];

int n;
LD poly_ans;

bool cmp(circle a,circle b)
{
	if(a.o==b.o) return a.r<b.r;
	return a.o<b.o;
}

node rot(node tmp,LD A)	//逆时针将x向量转过angle°角 
{
	return (node){ tmp.x*cos(A)-tmp.y*sin(A),
		tmp.x*sin(A)+tmp.y*cos(A)};
}

LD calc_S(LD A,LD r)
{
	return A*r;
//	return 0.5*sqr(r)*(A-sin(A));
}

LD calc_poly(node a,node b)
{
	return a^b * 0.5;
}

struct sege
{
	LD l,r;
}b[N<<1];

bool cmp1(sege a,sege b)
{
	return a.l < b.l;
}

LD calc(int x)
{
	LD ans=0;
	node p1 = a[x].o,p2;
	LD r1=a[x].r,r2;
	int cnt=0;
	for(int i=x+1;i<=n;i++)
	{
		p2=a[i].o, r2=a[i].r;
		LD d = dist(p1,p2);
		if(d >= r1+r2) continue;
		if(r1+d<=r2) return 0;
		if(r2+d<=r1) continue; 
		LD len1 = (sqr(r1)-sqr(r2)+sqr(d))/(2*d);
		LD angle1 = acos(len1/r1);
		node v0 = (p2-p1)/d*r1;
		node x1 = rot(v0,-angle1);
		node x2 = rot(v0,angle1);
		//
		poly_ans += calc_poly(x1,a[x].o);
		poly_ans += calc_poly(a[x].o,x2);
		//
	//	a[x].print();
	//	a[i].print();
	//	puts("cross");
		LD l = atan2(x1.y,x1.x);
		LD r = atan2(x2.y,x2.x);
	//	cout << l << ' ' <<  r  << endl; 
		if(l<0) l+=2*PI;
		if(r<0) r+=2*PI;
		if(l>r)
		{
			b[++cnt] = (sege){0.0,r};
			b[++cnt] = (sege){l,2*PI};
		}
		else b[++cnt] = (sege){l,r};
	}
	LD R=0;
	if(!cnt) return calc_S(2*PI,r1);
	sort(b+1,b+cnt+1,cmp1);
	R=b[1].r;
	for(int i=2;i<=cnt;i++)
	{
		if(b[i].l>R)
		{
			ans+=calc_S(b[i].l-R,r1);
			R=b[i].r;
		}
		else R=max(R,b[i].r);
	}
	ans+=calc_S(b[1].l-R+2*PI,r1);
	return ans;
}

int main()
{
//	freopen("test.txt","r",stdin);
	freopen("disc.in", "r",stdin);
	freopen("disc.out","w",stdout);
	while(~scanf("%d",&n))
	{
		LD ans=0;
		poly_ans=0;
		for(int i=1;i<=n;i++)
			scanf("%lf%lf%lf",&a[i].r,&a[i].o.x,&a[i].o.y);
	//	sort(a+1,a+n+1,cmp);
		for(int i=1;i<=n;i++) ans += calc(i);
		printf("%.3lf\n", ans/*+poly_ans*/);
	}
	return 0;
}