HDU 4720 Naive and Silly Muggles (简单计算几何)

Naive and Silly Muggles

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Problem Description
Three wizards are doing a experiment. To avoid from bothering, a special magic is set around them. The magic forms a circle, which covers those three wizards, in other words, all of them are inside or on the border of the circle. And due to save the magic power, circle's area should as smaller as it could be. Naive and silly "muggles"(who have no talents in magic) should absolutely not get into the circle, nor even on its border, or they will be in danger. Given the position of a muggle, is he safe, or in serious danger?
 

 

Input
The first line has a number T (T <= 10) , indicating the number of test cases. For each test case there are four lines. Three lines come each with two integers xi and yi (|xi, yi| <= 10), indicating the three wizards' positions. Then a single line with two numbers qx and qy (|qx, qy| <= 10), indicating the muggle's position.
 

 

Output
For test case X, output "Case #X: " first, then output "Danger" or "Safe".
 

 

Sample Input
3
0  0
2  0
1  2
1  -0.5
 
0  0
2  0
1  2
1  -0.6
 
0  0
3  0
1  1
1  -1.5
 

 

Sample Output
Case #1: Danger
Case #2: Safe
Case #3: Safe
 
 
source
 
题目大意:给出三点坐标,求一个包含此三点的面积最小的圆,这三点必须包含在圆里面或边界上,给出另一个D点的坐标,D点若在圆外则安全,否则危险。
题解:三点可确定一个面积最小的外接圆,但题目要求的圆可以包含点(点并不一定在圆上,可在圆内),所以有点可以不在圆上,故要判断最长的边的中点是否可以构成一个如题所要求的圆(若可构成,则这条直线的中点即为圆心,且圆心到第3个点的距离必须小于等于半径)。
 
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

int main()
{
    int T;
    int ans=1;
    double x1,y1,x2,y2,x3,y3,x,y,Max;
    double a0,b0,r;//外接圆圆心,半径
    double x0,y0,R;//最长边的中点,半径
    cin>>T;
    while(T--)
    {
        cin>>x1>>y1>>x2>>y2>>x3>>y3>>x>>y;
        //求外接圆的圆心和半径
        a0 = ((y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1)+(y2-y1)*(y1*y1-y3*y3+x1*x1-x3*x3))/(2*(x2-x1)*(y3-y1)-2*(x3-x1)*(y2-y1));
        b0 = ((x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1)+(x2-x1)*(x1*x1-x3*x3+y1*y1-y3*y3))/(2*(y2-y1)*(x3-x1)-2*(y3-y1)*(x2-x1));
        r=sqrt((x1-a0)*(x1-a0)+(y1-b0)*(y1-b0));
        
//判断最长边的中点构成的圆能否包含第三个点
double d1=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); double d2=sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)); double d3=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3)); double a1=x1,b1=y1,a2=x2,b2=y2,a=x3,b=x3; Max = d1; if(Max<d2) { Max = d2; a1 = x2;b1 = y2; a2 = x3;b2 = y3; a = x1;b = y1; } if(Max<d3) { Max = d3; a1 = x1;b1 = y1; a2 = x3;b2 = y3; a = x2;b = y2; } R = Max/2.0; x0 = (a1+a2)/2.0; y0 = (b1+b2)/2.0; double dir=sqrt((a-x0)*(a-x0)+(b-y0)*(b-y0)); //圆心与第3点的距离
bool flag = 0; if(dir<=R)//当圆心与第3个点的距离小于半径时,说明可以构成这个圆,此时只需判断此半径与外接圆的半径哪个最小即可
flag = 1; if(flag) { if(r<R) { double d = sqrt((x-a0)*(x-a0)+(y-b0)*(y-b0)); if(d<=r) printf("Case #%d: Danger\n",ans++); else printf("Case #%d: Safe\n",ans++); } else { double d = sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0)); if(d<=R) printf("Case #%d: Danger\n",ans++); else printf("Case #%d: Safe\n",ans++); } } else { double d = sqrt((x-a0)*(x-a0)+(y-b0)*(y-b0)); if(d<=r) printf("Case #%d: Danger\n",ans++); else printf("Case #%d: Safe\n",ans++); } } return 0; }

 

 

posted on 2013-09-11 20:45  落叶伴雨下  阅读(253)  评论(0)    收藏  举报

导航