标签:question sid lag border rom 面积 scribe depend find
Input
Output
Example
input | output |
---|---|
0 0 10 0 0 20 4 6 |
48.0000000000 4 |
-3 0 2 -1 5 7 0 1 |
9.0697674419 2 |
把三角形按锐角、直角、钝角分类讨论,看点p是否在三条高上。锐角三角形的答案在3-6之间,直角在3-4之间,钝角在1-2之间。
需要求点在直线上的射影,然后再相似三角形啦,正切函数啥的啦搞一下面积就出来了。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define EPS 0.00000001 struct Point { double x,y; Point(const double &X,const double &Y) { x=X; y=Y; } Point(){} double Length() { return sqrt(x*x+y*y); } }p,a[4]; typedef Point Vector; double Dot(const Vector &a,const Vector &b) { return a.x*b.x+a.y*b.y; } Vector operator - (const Vector &a,const Vector &b) { return Vector(a.x-b.x,a.y-b.y); } Vector operator + (const Vector &a,const Vector &b) { return Vector(a.x+b.x,a.y+b.y); } double Cross(const Vector &a,const Vector &b) { return a.x*b.y-a.y*b.x; } double DisToLine(Point P,Point A,Point B) { Vector v1=B-A,v2=P-A; return fabs(Cross(v1,v2))/v1.Length(); } double tanget(Point a,Point b,Point c)//a是顶点 { double COS=Dot(b-a,c-a)/(b-a).Length()/(c-a).Length(); double SIN=sqrt((1.0-COS*COS)); return SIN/COS; } Vector operator * (const double &x,const Vector &v) { return Vector(x*v.x,x*v.y); } Point GetLineProjection(Point P,Point A,Point B) { Vector v=B-A; return A+(Dot(v,P-A)/Dot(v,v))*v; } double area; int main() { //freopen("b.in","r",stdin); for(int i=1;i<=3;++i) scanf("%lf%lf",&a[i].x,&a[i].y); scanf("%lf%lf",&p.x,&p.y); int flag=0,ans=0; //钝角三角形 if(Dot(a[2]-a[1],a[3]-a[1])<-EPS) { double dis=DisToLine(p,a[2],a[3]); area=dis*((a[2]-a[3]).Length()-dis/tanget(a[2],a[1],a[3])-dis/tanget(a[3],a[1],a[2])); if(fabs(Dot(a[1]-p,a[2]-a[3]))<EPS) ans=1; else { ans=2; Point p1=GetLineProjection(a[1],a[2],a[3]); Point p2=GetLineProjection(p,a[2],a[3]); double h=(a[1]-p1).Length(); double h1; if(Dot(p-p1,a[2]-p1)>EPS) h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h; else h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h; double l1=(h-h1)/h*(a[2]-a[3]).Length(); area=max(area,h1*l1); } printf("%.10lf\n%d\n",area,ans); return 0; } else if(Dot(a[1]-a[2],a[3]-a[2])<-EPS) { double dis=DisToLine(p,a[1],a[3]); area=dis*((a[1]-a[3]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[3],a[1],a[2])); if(fabs(Dot(a[2]-p,a[1]-a[3]))<EPS) ans=1; else { ans=2; Point p1=GetLineProjection(a[2],a[1],a[3]); Point p2=GetLineProjection(p,a[1],a[3]); double h=(a[2]-p1).Length(); double h1; if(Dot(p-p1,a[1]-p1)>EPS) h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h; else h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h; double l1=(h-h1)/h*(a[1]-a[3]).Length(); area=max(area,h1*l1); } printf("%.10lf\n%d\n",area,ans); return 0; } else if(Dot(a[1]-a[3],a[2]-a[3])<-EPS) { double dis=DisToLine(p,a[1],a[2]); area=dis*((a[1]-a[2]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[2],a[1],a[3])); if(fabs(Dot(a[3]-p,a[1]-a[2]))<EPS) ans=1; else { ans=2; Point p1=GetLineProjection(a[3],a[1],a[2]); Point p2=GetLineProjection(p,a[1],a[2]); double h=(a[3]-p1).Length(); double h1; if(Dot(p-p1,a[1]-p1)>EPS) h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h; else h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h; double l1=(h-h1)/h*(a[1]-a[2]).Length(); area=max(area,h1*l1); } printf("%.10lf\n%d\n",area,ans); return 0; } //直角三角形 if(fabs(Dot(a[2]-a[1],a[3]-a[1]))<EPS) { double dis=DisToLine(p,a[2],a[3]); area=dis*((a[2]-a[3]).Length()-dis/tanget(a[2],a[1],a[3])-dis/tanget(a[3],a[1],a[2])); if(fabs(Dot(a[1]-p,a[2]-a[3]))<EPS) ans=3; else { ans=4; Point p1=GetLineProjection(a[1],a[2],a[3]); Point p2=GetLineProjection(p,a[2],a[3]); double h=(a[1]-p1).Length(); double h1; if(Dot(p-p1,a[2]-p1)>EPS) h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h; else h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h; double l1=(h-h1)/h*(a[2]-a[3]).Length(); area=max(area,h1*l1); Point p3=GetLineProjection(p,a[1],a[3]); double h2=(p3-a[3]).Length()/(a[1]-a[3]).Length()*(a[1]-a[2]).Length(); Point p4=GetLineProjection(p,a[1],a[2]); double l2=(a[1]-a[3]).Length()-h2/tanget(a[3],a[1],a[2]); area=max(area,h2*l2); double h3=(p4-a[2]).Length()/(a[1]-a[2]).Length()*(a[1]-a[3]).Length(); double l3=(a[1]-a[2]).Length()-h3/tanget(a[2],a[1],a[3]); area=max(area,h3*l3); } printf("%.10lf\n%d\n",area,ans); return 0; } else if(fabs(Dot(a[1]-a[2],a[3]-a[2]))<EPS) { double dis=DisToLine(p,a[1],a[3]); area=dis*((a[1]-a[3]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[3],a[1],a[2])); if(fabs(Dot(a[2]-p,a[1]-a[3]))<EPS) ans=3; else { ans=4; Point p1=GetLineProjection(a[2],a[1],a[3]); Point p2=GetLineProjection(p,a[1],a[3]); double h=(a[2]-p1).Length(); double h1; if(Dot(p-p1,a[1]-p1)>EPS) h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h; else h1=(p2-a[3]).Length()/(p1-a[3]).Length()*h; double l1=(h-h1)/h*(a[1]-a[3]).Length(); area=max(area,h1*l1); Point p3=GetLineProjection(p,a[2],a[3]); double h2=(p3-a[3]).Length()/(a[2]-a[3]).Length()*(a[1]-a[2]).Length(); Point p4=GetLineProjection(p,a[1],a[2]); double l2=(a[2]-a[3]).Length()-h2/tanget(a[3],a[1],a[2]); area=max(area,h2*l2); double h3=(p4-a[1]).Length()/(a[1]-a[2]).Length()*(a[2]-a[3]).Length(); double l3=(a[1]-a[2]).Length()-h3/tanget(a[1],a[2],a[3]); area=max(area,h3*l3); } printf("%.10lf\n%d\n",area,ans); return 0; } else if(fabs(Dot(a[1]-a[3],a[2]-a[3]))<EPS) { double dis=DisToLine(p,a[1],a[2]); area=dis*((a[1]-a[2]).Length()-dis/tanget(a[1],a[2],a[3])-dis/tanget(a[2],a[1],a[3])); if(fabs(Dot(a[3]-p,a[1]-a[2]))<EPS) ans=3; else { ans=4; Point p1=GetLineProjection(a[3],a[1],a[2]); Point p2=GetLineProjection(p,a[1],a[2]); double h=(a[3]-p1).Length(); double h1; if(Dot(p-p1,a[1]-p1)>EPS) h1=(p2-a[1]).Length()/(p1-a[1]).Length()*h; else h1=(p2-a[2]).Length()/(p1-a[2]).Length()*h; double l1=(h-h1)/h*(a[1]-a[2]).Length(); area=max(area,h1*l1); Point p3=GetLineProjection(p,a[2],a[3]); double h2=(p3-a[2]).Length()/(a[2]-a[3]).Length()*(a[1]-a[3]).Length(); Point p4=GetLineProjection(p,a[1],a[3]); double l2=(a[2]-a[3]).Length()-h2/tanget(a[2],a[1],a[3]); area=max(area,h2*l2); double h3=(p4-a[1]).Length()/(a[1]-a[3]).Length()*(a[2]-a[3]).Length(); double l3=(a[1]-a[3]).Length()-h3/tanget(a[1],a[2],a[3]); area=max(area,h3*l3); } printf("%.10lf\n%d\n",area,ans); return 0; } //锐角三角形 for(int i=1;i<=3;++i)//枚举上顶点 { int j,k; if(i==1) j=2,k=3; else if(i==2) j=3,k=1; else j=1,k=2; double dis=DisToLine(p,a[j],a[k]); area=max(area,dis*((a[j]-a[k]).Length()-dis/tanget(a[j],a[i],a[k])-dis/tanget(a[k],a[i],a[j]))); if(fabs(Dot(a[i]-p,a[k]-a[j]))<EPS) ++ans; else { ans+=2; Point p1=GetLineProjection(a[i],a[j],a[k]); Point p2=GetLineProjection(p,a[j],a[k]); double h=(a[i]-p1).Length(); double h1; if(Dot(p-p1,a[j]-p1)>EPS) h1=(p2-a[j]).Length()/(p1-a[j]).Length()*h; else h1=(p2-a[k]).Length()/(p1-a[k]).Length()*h; double l1=(h-h1)/h*(a[j]-a[k]).Length(); area=max(area,h1*l1); } } printf("%.10lf\n%d\n",area,ans); return 0; }
【计算几何】URAL - 2101 - Knight's Shield
标签:question sid lag border rom 面积 scribe depend find
原文地址:http://www.cnblogs.com/autsky-jadek/p/6303275.html