记录编号 171553 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2011]气场区域 最终得分 100
用户昵称 Gravatar炎帝 是否通过 通过
代码语言 C++ 运行时间 9.939 s
提交时间 2015-07-19 20:16:32 内存使用 0.32 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const double INF=1e8,eps=1e-8,Dnum=1000;
const int SIZEN=60;
#define sqr(x) ((x)*(x))
class Point{
public:
	double x,y;
};
void print(Point p){printf("(%lf %lf)",p.x,p.y);}
inline double dist(Point A,Point B){
	return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));
}
inline bool Solve_Quadratic(double a,double b,double c,double &x1,double &x2){//就是解二次方程
	double dlt=b*b-4*a*c;
	if(dlt<0) return false;
	dlt=sqrt(dlt);
	x1=(-b-dlt)/(2*a);
	x2=(-b+dlt)/(2*a);
	if(x1>=x2) swap(x1,x2);
	return true;
}
inline pair<double,double> Intersection(pair<double,double> a,pair<double,double> b){
	return make_pair(max(a.first,b.first),min(a.second,b.second));
}
inline bool Circle_Line_Intersection(double x0,double y0,double r,double t,double &x1,double &x2){
	//圆心(x0,y0)半径r的圆和直线y=t的相交部分
	//方程:(x^2)-(2x0x)+(x0^2)+((b-y0)^2)-(r^2)<=0
	return Solve_Quadratic(1,-2*x0,sqr(x0)+sqr(t-y0)-sqr(r),x1,x2);
}
inline void Segment_Field_Affect(Point A,Point B,double t,vector<pair<double,double> > &V){
	if(dist(A,B)<eps) return;
	//线段AB所产生的气场在直线y=t上的部分,如果有就压入V
	double x1,x2;
	if(Circle_Line_Intersection((A.x+B.x)/2,(A.y+B.y)/2,dist(A,B)/2,t,x1,x2))
		V.push_back(make_pair(x1,x2));
}
inline void Segment_Point_Field_Affect_Single(Point A,Point B,Point C,double t,vector<pair<double,double> > &V){
	//线段AB,点C共同产生的气场在直线y=t上的部分,这里只考虑AB的一个方向,如果有就压入V
	double x1,x2,x3=INF,x4=-INF;
	if(!Solve_Quadratic(1,-(A.x+C.x),A.x*C.x-(t-C.y)*(A.y-t),x1,x2)) return;
	Solve_Quadratic(1,-(B.x+C.x),B.x*C.x-(t-C.y)*(B.y-t),x3,x4);//如果求解失败,x3=INF和x4=-INF并未改变
	V.push_back(Intersection(make_pair(x1,x2),make_pair(-INF,x3)));
	V.push_back(Intersection(make_pair(x1,x2),make_pair(x4,INF)));
}
inline void Segment_Point_Field_Affect(Point A,Point B,Point C,double t,vector<pair<double,double> > &V){
	if(dist(A,B)<eps) return;
	Segment_Point_Field_Affect_Single(A,B,C,t,V);
	Segment_Point_Field_Affect_Single(B,A,C,t,V);
}
inline void Segment_Segment_Field_Affect(Point A,Point B,Point C,Point D,double t,vector<pair<double,double> > &V){
	Segment_Point_Field_Affect(A,B,C,t,V);
	Segment_Point_Field_Affect(A,B,D,t,V);
	Segment_Point_Field_Affect(C,D,A,t,V);
	Segment_Point_Field_Affect(C,D,B,t,V);
}
int N;
double Xmax,Ymax;
Point seg[SIZEN][2];
inline double Calc_Quiet_Len(double t){
	static vector<pair<double,double> > cov;
	cov.clear();
	for(int i=1;i<=N;i++) Segment_Field_Affect(seg[i][0],seg[i][1],t,cov);
	for(int i=1;i<=N;i++)
		for(int j=1;j<i;j++)
			Segment_Segment_Field_Affect(seg[i][0],seg[i][1],seg[j][0],seg[j][1],t,cov);
	sort(cov.begin(),cov.end());
	double now=0,ans=0;
	for(int i=0;i<cov.size();i++){
		if(cov[i].first>Xmax) break;
		if(cov[i].first>now) ans+=cov[i].first-now;
		now=max(now,cov[i].second);
	}
	if(now<=Xmax) ans+=Xmax-now;
	return ans;
}
void Process(void){
	double d=Ymax/Dnum,ans=0;
	for(int i=0;i<Dnum;i++)	ans+=d*Calc_Quiet_Len(d*i);
	printf("%lf\n",ans/(Xmax*Ymax));
}
void Read(void){
	scanf("%d",&N);
	scanf("%lf%lf",&Xmax,&Ymax);
	for(int i=1;i<=N;i++) scanf("%lf%lf%lf%lf",&seg[i][0].x,&seg[i][0].y,&seg[i][1].x,&seg[i][1].y);
}
int main(){
	freopen("nt2011_region.in","r",stdin);
	freopen("nt2011_region.out","w",stdout);
	Read();
	Process();
	return 0;
}