这题有2种情况可以满足棍子不掉落
1、重心在某个圆内部
2、重心两侧的棍身都分别有支撑圆
只需通过遍历圆然后判断即可
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#define eps 0.01
#define pi 3.1415926
using namespace std;
struct circle {
double x, y, r;
void sc() {
scanf("%lf%lf%lf", &x, &y, &r);
}
} cir[10000];
double getdis(double x1, double y1, double x2, double y2) {
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
double getcos(double a, double b, double c) {
return (b * b + c * c - a * a) / (2.0 * b * c);
}
double crossed(double x1, double y1, double x2, double y2) {
return x1 * y2 - y1 * x2;
}
int main() {
int n, i, dir1, dir2, flag;
double x1, y1, x2, y2, len, gx, gy, a, b, c, C, A, x, y, r, area, h;
while (scanf("%d", &n) && n) {
for (i = 0; i < n; i++) {
cir[i].sc();
}
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
dir1 = 0;
dir2 = 0;
flag = 0;
len = getdis(x1, y1, x2, y2);
gx = (x1 + x2) / 2.0;
gy = (y1 + y2) / 2.0;
for (i = 0; i < n; i++) {
x = cir[i].x;
y = cir[i].y;
r = cir[i].r;
//1、重心上有支撑桌
//重心在圆内部
if (getdis(x, y, gx, gy) < r) {
flag = 1;
break;
}
//2、两侧都有支持桌:
//线段一端在圆内部
if (getdis(x1, y1, x, y) < r) {
dir1++;
if (dir2) {
flag = 1;
break;
}
continue;
}
if (getdis(x2, y2, x, y) < r) {
dir2++;
if (dir1) {
flag = 1;
break;
}
continue;
}
//线段两端在圆外部
a = getdis(x1, y1, x, y);
b = len;
c = getdis(x2, y2, x, y);
C = acos(getcos(c, a, b));
A = acos(getcos(a, b, c));
if (C < acos(0) && A < acos(0)) {
area = fabs(crossed(x - x1, y - y1, x2 - x1, y2 - y1));
h = area / len;
if (h < r) {
if (a < c) {
dir1++;
if (dir2) {
flag = 1;
break;
}
continue;
} else {
dir2++;
if (dir1) {
flag = 1;
break;
}
continue;
}
}
}
}
if (flag) {
printf("STAY\n");
} else {
printf("FALL\n");
}
}
}