这个题自认为写的代码比较挫。 = = 。没办法,比赛嘛,能A就行。
说下题意:告诉你三个点的坐标,由这三个画成的三角形构成一个面积最小的圆。然后再判断另外一个点跟这个圆的关系。
证明得:当三角形为锐角三角形或直角三角形的时候,三角形的外接圆是面积最小的圆。
当三角形为钝角三角形时,圆心钝角所对的边的中点时圆的面积最小。圆的半径是长边的一半。
然后思路就这些了。具体实现看代码吧。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
typedef struct
{
double x,y;
}Point;
typedef struct
{
Point p[3];
}Traingle;
typedef struct
{
Point center;
double r;
}Circle;
double Dis(Point p,Point q)
{
double dx=p.x-q.x;
double dy=p.y-q.y;
return sqrt(dx*dx+dy*dy);
}
double Area(Traingle ct)/*求三角形面积*/
{
return fabs((ct.p[1].x-ct.p[0].x)*(ct.p[2].y-ct.p[0].y)-(ct.p[2].x-ct.p[0].x)*(ct.p[1].y-ct.p[0].y))/2.0;
}
Circle CircumCircle(Traingle t)/*求外接圆*/
{
Circle tmp;
double a, b, c, c1, c2;
double xA, yA, xB, yB, xC, yC;
a = Dis(t.p[0], t.p[1]);
b = Dis(t.p[1], t.p[2]);
c = Dis(t.p[2], t.p[0]);
tmp.r = (a*b*c)/(Area(t)*4.0);
xA = t.p[0].x;
yA = t.p[0].y;
xB = t.p[1].x;
yB = t.p[1].y;
xC = t.p[2].x;
yC = t.p[2].y;
c1 = (xA*xA+yA*yA - xB*xB-yB*yB) / 2;
c2 = (xA*xA+yA*yA - xC*xC-yC*yC) / 2;
tmp.center.x = (c1*(yA - yC)-c2*(yA - yB)) / ((xA - xB)*(yA - yC)-(xA - xC)*(yA - yB));
tmp.center.y = (c1*(xA - xC)-c2*(xA - xB)) / ((yA - yB)*(xA - xC)-(yA - yC)*(xA - xB));
return tmp;
}
double cos(double a,double b,double c)
{
return (pow(a,2) + pow(b,2) - pow(c,2))/2*a*b;
}
int main()
{
int ncase;
Point point[10];
double Line[10];
double Cos[10];
scanf("%d",&ncase);
int K = 0;
while(ncase--)
{
Traingle ct;
Circle ans;
bool flag = false;
for(int i = 0 ; i < 4 ; i++)
{
scanf("%lf %lf",&point[i].x,&point[i].y);
ct.p[i] = point[i];
}
Line[0] = Dis(point[0],point[1]);
Line[1] = Dis(point[1],point[2]);
Line[2] = Dis(point[2],point[0]);
Cos[0] = cos(Line[0],Line[1],Line[2]);
Cos[1] = cos(Line[0],Line[2],Line[1]);
Cos[2] = cos(Line[1],Line[2],Line[0]);
printf("Case #%d: ",++K);
for(int i = 0 ; i < 3 ; i++)
{
if(Cos[i] < 0)
{
flag = true;
break;
}
}
if(flag == true)
{
double mx = 0.0;
int a,x1,x2;
for(int i = 0 ; i < 3 ; i++)
{
if(mx < Line[i])
{
mx = Line[i];
a = i;
}
}
if(a == 0)
{
x1 = 0;
x2 = 1;
}
else if(a == 1)
{
x1 = 1;
x2 = 2;
}
else
{
x1 = 2;
x2 = 0;
}
double R = mx/2;
Point centerx;
centerx.x = (point[x1].x + point[x2].x)/2;
centerx.y = (point[x1].y + point[x2].y)/2;
if(Dis(centerx,point[3]) > R)
{
printf("Safe\n");
}
else
{
printf("Danger\n");
}
}
else
{
ans = CircumCircle(ct);
double k = Dis(ans.center,point[3]);
if(k > ans.r)
{
printf("Safe\n");
}
else
{
printf("Danger\n");
}
}
}
return 0;
}