13成都邀请赛 1005 Naive and Silly Muggles
题目地址 :http://acm.hdu.edu.cn/showproblem.php?pid=4720
题目是给三个点 ,要求求出最小的能覆盖这三个点的圆,然后判断第四个点在不在这个圆内。
如果这个是一个钝角三角形,那么圆心就是最长边的中点,如果是锐角三角形,圆心就是外接圆圆心。 然后用点到圆心的距离和半径的关系判断是不是在圆内。
求外接圆时 用到向量点积为0,还有Crammer法则解方程
代码:
#include<iostream> #include<cstdio> using namespace std; double calcdet(double p[2][2] ) //计算行列式的值 { double ans=p[0][0]*p[1][1]-p[1][0]*p[0][1]; return ans; } int main() { double xa,ya,xb,yb,xc,yc,xm,ym,xd,yd,xe,ye,b1,b2; //d是ab中点 e是ac中点 int T; cin>>T; int index=0; while(T--) { scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&xa,&ya,&xb,&yb,&xc,&yc,&xm,&ym); double ac=(xa-xc)*(xa-xc)+(ya-yc)*(ya-yc); double ab=(xa-xb)*(xa-xb)+(ya-yb)*(ya-yb); double bc=(xb-xc)*(xb-xc)+(yb-yc)*(yb-yc); double x,y; int tag=0; if(ac+ab<=bc) { x=(xb+xc)/2; y=(yb+yc)/2; tag++; } else if(ac+bc<=ab) { x=(xa+xb)/2; y=(ya+yb)/2; tag++; } else if(bc+ab<=ac) { x=(xa+xc)/2; y=(ya+yc)/2; tag++; } if(tag==0) { double p[2][2]; p[0][0]=xb-xa; p[0][1]=yb-ya; p[1][0]=xc-xa; p[1][1]=yc-ya; xd=(xa+xb)/2; yd=(ya+yb)/2; xe=(xa+xc)/2; ye=(ya+yc)/2; b1=xd*(xb-xa)+yd*(yb-ya); b2=xe*(xc-xa)+ye*(yc-ya); double D=calcdet(p); p[0][0]=b1; p[1][0]=b2; double Dx=calcdet(p); p[0][0]=xb-xa; p[0][1]=b1; p[1][0]=xc-xa; p[1][1]=b2; double Dy=calcdet(p); x=Dx/D; y=Dy/D; } double R=(xa-x)*(xa-x)+(ya-y)*(ya-y); double dis=(xm-x)*(xm-x)+(ym-y)*(ym-y); index++; cout<<"Case #"<<index<<": "; if(dis>R) cout<<"Safe"<<endl; else cout<<"Danger"<<endl; } }