首页 > 代码库 > BZOJ 2508 简单题 数学算法

BZOJ 2508 简单题 数学算法

题目大意:维护一个平面,支持三种操作:

0.加入一条直线(给的是两点式)

1.删除一条直线

2.询问到所有直线距离平方和最小的点

题解见 http://blog.sina.com.cn/s/blog_ab8386bc0101i1nj.html

我只是贴代码供参考的- -

注意我的abcdef和题解设的不一样- -

这简单题WA了两页- -

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 120100
#define EPS 1e-7
using namespace std;
struct Line{
	double A,B,C;
	Line() {}
	Line(double x1,double y1,double x2,double y2)
	{
		A=y1-y2;
		B=x2-x1;
		C=x1*y2-x2*y1;
	}
}lines[M];
int n,tot;
double a,b,c,d,e,f;
//ans=a*x^2+b*y^2+c+d*x*y+e*x+f*y
int main()
{
	int i,p,x;
	double x1,y1,x2,y2;
	double A,B,C,temp;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&p);
		switch(p)
		{
			case 0:
				scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
				lines[++tot]=Line(x1,y1,x2,y2);
				A=lines[tot].A;
				B=lines[tot].B;
				C=lines[tot].C;
				temp=A*A+B*B;
				a+=A*A/temp;
				b+=B*B/temp;
				c+=C*C/temp;
				d+=2*A*B/temp;
				e+=2*A*C/temp;
				f+=2*B*C/temp;
				break;
			case 1:
				scanf("%d",&x);
				A=lines[x].A;
				B=lines[x].B;
				C=lines[x].C;
				temp=A*A+B*B;
				a-=A*A/temp;
				b-=B*B/temp;
				c-=C*C/temp;
				d-=2*A*B/temp;
				e-=2*A*C/temp;
				f-=2*B*C/temp;
				break;
			case 2:
				if(fabs(d*d-4*a*b)<EPS)
				{
					if(fabs(a)>EPS||fabs(d)>EPS) A=2*a,B=d,C=e;
					else if(fabs(b)>EPS||fabs(d)>EPS) A=d,B=2*b,C=f;
					else
					{
						printf("%.2lf\n",0.0);
						break;
						//这里我不明白为什么 望高人指点 
					}
					if(fabs(B)<EPS) x1=-C/A,y1=0;
					else x1=0,y1=-C/B;
				}
				else
				{
					double a1=2*a,b1=d,c1=e;
					double a2=d,b2=2*b,c2=f;
    				x1=(c2*b1-c1*b2)/(a1*b2-a2*b1);
    				y1=(a1*c2-a2*c1)/(a2*b1-a1*b2);
    			}
				printf("%.2lf\n", a*x1*x1+b*y1*y1+c+d*x1*y1+e*x1+f*y1 );
    			break;
		}
	}
	return 0;
}



BZOJ 2508 简单题 数学算法