题目链接:hdu 4720 Naive and Silly Muggles
题目大意:给出三点,找出一个圆,要求面积尽量小,并且三点必须在园内,如果可以找到一个圆,使得说第4个点不在圆内则是安全的。
解题思路:面积最小即三个点外切圆,根据三角形两条边的垂直平分线求出圆心。判断第4个点是否在圆内只要计算距离即可。
然后还要考虑说面积和外切圆相同,但是圆心不同的圆。
#include <cstdio>
#include <cstring>
#include <cmath>
const double eps = 1e-9;
struct point {
double x, y;
}p[3], o, e;
struct line {
double A, B, C;
}l[3];
inline double dis (double x, double y) {
return x * x + y * y;
}
line getline (double a, double b, double x, double y) {
line cur;
cur.A = a;
cur.B = b;
cur.C = -(a*x + b*y);
return cur;
}
point getP(line a, line b) {
point cur;
cur.x = (b.C*a.B - a.C*b.B)/(a.A*b.B - b.A*a.B);
cur.y = (b.C*a.A - a.C*b.A)/(a.B*b.A - b.B*a.A);
return cur;
}
void init () {
for (int i = 0; i < 3; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
for (int i = 0; i < 3; i++)
l[i] = getline(p[i].x - p[i+1].x, p[i].y - p[i+1].y, (p[i].x+p[i+1].x)/2, (p[i].y+p[i+1].y)/2);
scanf("%lf%lf", &e.x, &e.y);
o = getP(l[0], l[1]);
}
bool judge () {
double r = dis(o.x - p[0].x, o.y - p[0].y);
point oo;
double d = dis(o.x - e.x, o.y - e.y);
if (d > r)
return false;
for (int i = 0; i < 3; i++) {
int k = (i+1)%3;
int t = 3 - i - k;
line a = getline(p[k].y - p[i].y, p[i].x - p[k].x, p[i].x, p[i].y);
line b = getline(p[i].x - p[k].x, p[i].y - p[k].y, o.x, o.y);
point cur = getP(a, b);
oo.x = 2*cur.x - o.x;
oo.y = 2*cur.y - o.y;
if (dis(oo.x - p[t].x, oo.y - p[t].y) > r)
continue;
if (dis(oo.x - e.x, oo.y - e.y) > r)
return false;
}
return true;
}
int main () {
int cas;
scanf("%d", &cas);
for (int i = 1; i <= cas; i++) {
init ();
printf("Case #%d: %s\n", i, judge() ? "Danger" : "Safe");
}
return 0;
}