HDU 4720 Naive and Silly Muggles(三角形最小覆盖圆)

本文介绍了一个算法问题——如何判断一个人是否处于由三个巫师形成的最小魔法圈内或边界上。通过分析三角形类型来确定圆心,进而判断指定位置的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Naive and Silly Muggles

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1236    Accepted Submission(s): 828


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 x i and y i (|x i, y i| <= 10), indicating the three wizards' positions. Then a single line with two numbers q x and q y (|q x, q y| <= 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
 
分析 : 题目中要求找到最小的圆将巫师覆盖,最小覆盖圆,并不完全是外接圆。根据三角形的分类,确定求解圆心的方法;详见代码注释。
附:外接圆心求解公式: 点击打开链接

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;

struct Node {
	double xA,xB,yA,yB;
	double dis;
}edge[3];
double dis(double x1,double y1,double x2,double y2)
{
	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);//一点小小心得:实际有时候不用返回sqrt后的结果,只是用来比较而已,还能节省时间复杂度
}
int judge(double x1,double x2,double x3,double y1,double y2,double y3)
{
	if(dis(x1,y1,x2,y2)+dis(x1,y1,x3,y3) < dis(x2,y2,x3,y3))
		return 0;
	if(dis(x1,y1,x3,y3)+dis(x2,y2,x3,y3) < dis(x1,y1,x2,y2))
		return 0;
	if(dis(x2,y2,x3,y3)+dis(x1,y1,x2,y2) < dis(x1,y1,x3,y3))
		return 0;
	return 1;
}
int main()
{
	int t;
	int inde=1;
	double A,B,C,G;
	double x1,x2,x3,y1,y2,y3,x0,y0;
	double X,Y;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x0,&y0);
		if(judge(x1,x2,x3,y1,y2,y3))	//如果是直角或锐角三角形,则需求外接圆的圆心 
		{
			A=x1*x1+y1*y1;	B=x2*x2+y2*y2;	C=x3*x3+y3*y3;
			G=(y3-y2)*x1+(y1-y3)*x2+(y2-y1)*x3;
			X=((B-C)*y1+(C-A)*y2+(A-B)*y3)/2/G; 
			Y=((C-B)*x1+(A-C)*x2+(B-A)*x3)/2/G;
		}
		else	//如果存在两条边的平方和小于第三遍,则一定是钝角三角形,此时的圆心在钝角对应的边的中点 
		{
			edge[0].xA=x1; edge[0].yA=y1; edge[0].xB=x2; edge[0].yB=y2;
			edge[0].dis=dis(x1,y1,x2,y2);
			edge[1].xA=x1; edge[1].yA=y1; edge[1].xB=x3; edge[1].yB=y3;
			edge[1].dis=dis(x1,y1,x3,y3);
			edge[2].xA=x2; edge[2].yA=y2; edge[2].xB=x3; edge[2].yB=y3;
			edge[2].dis=dis(x2,y2,x3,y3);
			int mai=0;
			for(int i=1;i<3;i++)
			{
				if(edge[mai].dis<edge[i].dis)
					mai=i;
			}
			X=(edge[mai].xA+edge[mai].xB)/2;
			Y=(edge[mai].yA+edge[mai].yB)/2;
		}
		if(dis(X,Y,x0,y0)>dis(X,Y,x1,y1))	//根据得到的圆心求解是否在安全区	
			printf("Case #%d: Safe\n",inde++);
		else
			printf("Case #%d: Danger\n",inde++);
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值