题目大意:给出三个点,确定一个包含三个点的最小圆,然后判断点p是否在圆内(包括边上)还是圆外,
前者输出Danger,后者输出Safe。
解题思路: 1)如果三点共线,则最小圆的圆心即为最长边的中点
2)如果三点构成的三角形是锐角三角形,则最小圆的圆心即为三角形的外心
3)如果三点构成的三角形是钝角三角形或直角三角形,则最小圆的圆心为三角形最长边的中点
代码如下:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define eps 1e-6
struct point
{
double x,y;
}p[4], re;
double ma = 0;
struct line
{
point a,b;
};
double dis(point p1, point p2)
{
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
double mult(point p1,point p2,point p0)
{
return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
point intersection(line u, line v)
{
point ret = u.a;
double t = ((u.a.x - v.a.x) * (v.a.y - v.b.y) - (u.a.y - v.a.y) * (v.a.x - v.b.x))
/ ((u.a.x - u.b.x) * (v.a.y - v.b.y) - (u.a.y - u.b.y) * (v.a.x - v.b.x));
ret.x += (u.b.x-u.a.x) * t;
ret.y += (u.b.y-u.a.y) * t;
return ret;
}
point circumcenter(point a, point b, point c)
{
line u, v;
u.a.x = (a.x + b.x)/2;
u.a.y = (a.y + b.y)/2;
u.b.x = u.a.x - a.y + b.y;
u.b.y = u.a.y + a.x - b.x;
v.a.x = (a.x + c.x)/2;
v.a.y = (a.y + c.y)/2;
v.b.x = v.a.x - a.y + c.y;
v.b.y = v.a.y + a.x - c.x;
return intersection(u, v);
}
void init()
{
double r1 = dis(p[0], p[1]);
double r2 = dis(p[1], p[2]);
double r3 = dis(p[0], p[2]);
if(ma < r1)
{
ma = r1/2;
re.x = (p[0].x + p[1].x)/2;
re.y = (p[0].y + p[1].y)/2;
}
if(ma < r2)
{
ma = r2/2;
re.x = (p[1].x + p[2].x)/2;
re.y = (p[2].y + p[1].y)/2;
}
if(ma < r3)
{
ma = r3/2;
re.x = (p[0].x + p[2].x)/2;
re.y = (p[0].y + p[2].y)/2;
}
}
bool judge(double r1, double r2, double r3)
{
double rest = r1 * r1 + r2 * r2 - r3 * r3;
if(rest <= 0) return true;
return false;
}
int main()
{
int t;
scanf("%d", &t);
for(int i = 1; i <= t; i ++)
{
for(int j = 0; j < 4; j ++)
{
scanf("%lf %lf", &p[j].x, &p[j].y);
}
if(mult(p[0], p[1], p[2]) == 0)
{
init();
}
else
{
double r1 = dis(p[0], p[1]);
double r2 = dis(p[1], p[2]);
double r3 = dis(p[0], p[2]);
if(judge(r1, r2, r3) || judge(r1, r3, r2) || judge(r3, r2, r1))
init();
else
{
re = circumcenter(p[0], p[1], p[2]);
ma = dis(re, p[0]);
}
}
if(dis(re, p[3]) > ma)
{
printf("Case #%d: Safe\n", i);
}
else
{
printf("Case #%d: Danger\n", i);
}
}
return 0;
}