题目大意:
加入直线,删除直线,求点到所有直线的距离的平方和。
题解:
把点到直线的距离公式写出来,然后展开。维护六个值,计算一个二元的多项式的最小值。
对x和y分别求导,导数都为零时取到极值。然后解一个方程组。
要各种讨论,方程的解可能不唯一,任取一个。
代码:
#include<cstdio> #define eps 1e-7 using namespace std; double x1[1000005],y1[1000005],x2[1000005],y2[1000005],A,B,C,D,E,F; double abs1(double x){ if (x<0) return -x; return x; } int main(){ int t; scanf("%d",&t); int cnt=0; while (t--){ int cas; scanf("%d",&cas); if (cas==0){ cnt++; scanf("%lf%lf%lf%lf",&x1[cnt],&y1[cnt],&x2[cnt],&y2[cnt]); double ai=y1[cnt]-y2[cnt],bi=x2[cnt]-x1[cnt],ci=x1[cnt]*y2[cnt]-x2[cnt]*y1[cnt]; A+=ai*ci*2/(ai*ai+bi*bi); B+=bi*ci*2/(ai*ai+bi*bi); C+=ai*bi*2/(ai*ai+bi*bi); D+=ai*ai/(ai*ai+bi*bi); E+=bi*bi/(ai*ai+bi*bi); F+=ci*ci/(ai*ai+bi*bi); } else if (cas==1){ int id; scanf("%d",&id); double ai=y1[id]-y2[id],bi=x2[id]-x1[id],ci=x1[id]*y2[id]-x2[id]*y1[id]; A-=ai*ci*2/(ai*ai+bi*bi); B-=bi*ci*2/(ai*ai+bi*bi); C-=ai*bi*2/(ai*ai+bi*bi); D-=ai*ai/(ai*ai+bi*bi); E-=bi*bi/(ai*ai+bi*bi); F-=ci*ci/(ai*ai+bi*bi); } else if (cas==2){ double x,y; if (abs1(C*C-4*D*E)<eps){ double a1,b1,c1; if (abs1(D)>eps || abs1(C)>eps) a1=2*D,b1=C,c1=A; else if (abs1(E)>eps || abs1(C)>eps) a1=C,b1=2*E,c1=B; else { printf("%.2lf ",0.0); continue; } if (abs1(E)<eps) x=-c1/a1,y=0; else x=0,y=-c1/b1; } else if (abs1(C)<eps){ if (abs1(D)<eps) x=0; else x=-A/(D*2); if (abs1(E)<eps) y=0; else y=-B/(E*2); } else if (abs1(D)<eps){ y=-A/C; x=(-E*y*2-B)/C; } else if (abs1(E)<eps){ x=-B/C; y=(-x*D*2-A)/C; } else{ if (abs1(E*2-C*C/(D*2))<eps) { printf("0.00 "); continue; } y=(-B+A*C/(D*2))/(E*2-C*C/(D*2)); x=(-A-C*y)/(D*2); } printf("%.2f ",A*x+B*y+C*x*y+D*x*x+E*y*y+F); } } return 0; }