3.7牛客2021年度训练联盟热身训练赛第一场A.Weird Flecks, But OK[最小覆盖圆]

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述 

An artist who wanted to create an installation where his works appeared to be floating in midair has cast a large cube of clear acrylic to serve as a base. Unfortunately, during the casting, some small flecks of dirt got into the mix, and now appear as a cluster of pinpoint flaws in the otherwise clear cube. 

He wants to drill out the portion of the cube containing the flaws so that he can plug the removed volume with new, clear acrylic. He would prefer to do this in one drilling step. For stability’s sake, the drill must enter the cube only once, perpendicular to one of its faces. The cube’s faces are parallel to the coordinate axes. 

Given the (x,y,z) positions of the flaws, and treating the size of the flaws as negligible, what is the smallest diameter drill bit that can be used to remove the flaws in one operation?? 

输入描述:

 

The first line of input contains an integer N denoting the number of flaws. 3≤N≤5000

This is followed by N lines of input, each containing three real numbers in the range −1000.0…1000.0, denoting the (x,y,z) coordinates of a single flaw. Each number contains at most 6 digits following a decimal point. The decimal point may be omitted if all succeeding digits are zero.

输出描述:

 

Print the diameter of the smallest drill bit that would remove all the flaws.

The answer is considered correct if the absolute or relative error is less than 10-4

示例1

输入

复制

3
1.0 0.0 1.4
-1.0 0.0 -1.4
0.0 1.0 -0.2

输出

复制

2.0000000000

示例2

输入

复制

5
1.4 1.0 0.0
-0.4 -1.0 0.0
-0.1 -0.25 -0.5
-1.2 0.0 0.9
0.2 0.5 0.5

输出

复制

2.0000000000

示例3

输入

复制

8
435.249 -494.71 -539.356
455.823 -507.454 -539.257
423.394 -520.682 -538.858
446.507 -501.953 -539.37
434.266 -503.664 -560.631
445.059 -549.71 -537.501
449.65 -506.637 -513.778
456.05 -499.715 -561.329

输出

复制

49.9998293198

【最小覆盖圆】

知识点:https://blog.csdn.net/WhereIsHeroFrom/article/details/79531050

队友代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
 
const double eps = 1e-8;
 
struct node{
	double x,y;
};
struct temp{
	double x,y,z;
};
 
struct node p[5010],central;
struct temp t[5010];
double ansR=0x3f3f3f;
int n;
 
double dist(struct node  a,struct node b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
 
 
//求外接圆圆心,根据三边相等
struct node circumcenter(struct node a,struct node b,struct node c)
{
	double a1=b.x-a.x, b1=b.y-a.y, c1=(a1*a1+b1*b1)/2;
	double a2=c.x-a.x, b2=c.y-a.y, c2=(a2*a2+b2*b2)/2;
	double d=a1*b2-a2*b1;
	struct node tmp;
	tmp.x = a.x + (c1*b2-c2*b1)/d ;
	tmp.y = a.y+(a1*c2-a2*c1)/d;
	return tmp;
}
 
void min_cover_circle(){
	random_shuffle(p,p+n); 
	central = p[0];
	int i,j,k;
	double R=0;
	for(i=1;i<n;i++){
		if(dist(central,p[i])+eps>R){
			central = p[i];
			R=0;
			for(j=0;j<i;j++){
				if(dist(central,p[j])+eps>R){
					central.x=(p[i].x+p[j].x)/2;
					central.y=(p[i].y+p[j].y)/2;
					R=dist(central,p[j]);
					for(k=0;k<j;k++){
						if(dist(central,p[k])+eps>R){
							central=circumcenter(p[i],p[j],p[k]);
							R=dist(central,p[k]);
						}
					}
				}
			}
		}
	}
	ansR=min(ansR,R);
}

 
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		scanf("%lf%lf%lf",&t[i].x,&t[i].y,&t[i].z);
	}
	for(int i=0;i<n;i++) {
		p[i].x=t[i].x;	p[i].y=t[i].y;
	} 
	min_cover_circle();
	for(int i=0;i<n;i++) {
		p[i].x=t[i].z;	p[i].y=t[i].y;
	} 
	min_cover_circle();
	for(int i=0;i<n;i++) {
		p[i].x=t[i].z;	p[i].y=t[i].x;
	} 
	min_cover_circle();
//	printf("(%.1lf,%.1lf).\n%.1lf\n",central.x,central.y,R);
	printf("%.10f\n",2*ansR); 
	return 0;
}

自己代码

拿下面代码改的

https://blog.csdn.net/Vmurder/article/details/46605193?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161510137816780255278832%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161510137816780255278832&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~hot_rank-6-46605193.pc_search_result_before_js&utm_term=2823信号塔

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
#define Inf 0xfffffff
#define N 501000
#define eps 1e-7
using namespace std;

double min_r=Inf;

struct Point
{
    double x,y;
    Point(double _x=0,double _y=0):x(_x),y(_y)
    {
        x=_x;
        y=_y;
    }
    void read(){scanf("%lf%lf",&x,&y);}
    bool operator < (const Point &A)const
    {return fabs(x-A.x)<eps?y<A.y:x<A.x;}
    double operator - (const Point &A)const
    {return sqrt((x-A.x)*(x-A.x)+(y-A.y)*(y-A.y));}
    void print(){printf("%.2lf %.2lf ",x,y);}
}p1[N],p2[N],p3[N];

struct Circle
{
    Point c; // center
    double r;
    Circle(Point _c=Point(0,0),double _r=0):c(_c),r(_r){}
    bool operator ^ (const Point &A)const{return A-c>r+eps;} // 包含
    void print()
    {
        //c.print();
        if(r<min_r)
            min_r=r;
    }
};

inline double xmul(const Point &A,const Point &B,const Point &C)
{return (C.y-A.y)*(B.x-A.x)-(B.y-A.y)*(C.x-A.x);}

struct Get_Convex_Hull
{//求凸包
    int stk1[N],top1,stk2[N],top2;
    Point tp[N];
    void work(Point *p,int &n)
    {
        int i;
        sort(p+1,p+n+1);

        stk1[top1=1]=1;
        for(i=2;i<=n;i++)
        {
            while(top1>1&&xmul(p[stk1[top1-1]],p[stk1[top1]],p[i])>-eps)top1--;
            stk1[++top1]=i;
        }
        stk2[top2=1]=n;
        for(i=n-1;i;i--)
        {
            while(top2>1&&xmul(p[stk2[top2-1]],p[stk2[top2]],p[i])>-eps)top2--;
            stk2[++top2]=i;
        }
        n=0;
        for(i=1;i<top1;i++)tp[++n]=p[stk1[i]];
        for(i=1;i<top2;i++)tp[++n]=p[stk2[i]];
        for(i=1;i<=n;i++)p[i]=tp[i];
    }
}gch;

struct Get_Min_Circle_Cover1
{
    Point circumcenter(const Point &a,const Point &b,const Point &c)
    {//返回三角形的外心 我并不知道这是什么鬼。。好强的样子。
        Point ret;
        double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;
        double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;
        double d=a1*b2-a2*b1;
        ret.x=a.x+(c1*b2-c2*b1)/d;
        ret.y=a.y+(a1*c2-a2*c1)/d;
        return ret;
    }
    Circle work(int n)
    {
        random_shuffle(p1+1,p1+n+1);
        Circle C=Circle(p1[1],0);
        int i,j,k;

        for(i=2;i<=n;i++)if(C^p1[i])
        {
            C=Circle(p1[i],0);
            for(j=1;j<i;j++)if(C^p1[j])
            {
                C.c=Point((p1[i].x+p1[j].x)/2,(p1[i].y+p1[j].y)/2);
                C.r=p1[j]-C.c;
                for(k=1;k<j;k++)if(C^p1[k])//求外接圆圆心,要求三点不能共线
                    C.c=circumcenter(p1[i],p1[j],p1[k]),C.r=C.c-p1[i];

            }
        }
        return C;
    }
}gmcc1;

struct Get_Min_Circle_Cover2
{
    Point circumcenter(const Point &a,const Point &b,const Point &c)
    {//返回三角形的外心 我并不知道这是什么鬼。。好强的样子。
        Point ret;
        double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;
        double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;
        double d=a1*b2-a2*b1;
        ret.x=a.x+(c1*b2-c2*b1)/d;
        ret.y=a.y+(a1*c2-a2*c1)/d;
        return ret;
    }
    Circle work(int n)
    {
        random_shuffle(p2+1,p2+n+1);
        Circle C=Circle(p2[1],0);
        int i,j,k;

        for(i=2;i<=n;i++)if(C^p2[i])
        {
            C=Circle(p2[i],0);
            for(j=1;j<i;j++)if(C^p2[j])
            {
                C.c=Point((p2[i].x+p2[j].x)/2,(p2[i].y+p2[j].y)/2);
                C.r=p2[j]-C.c;
                for(k=1;k<j;k++)if(C^p2[k])//求外接圆圆心,要求三点不能共线
                    C.c=circumcenter(p2[i],p2[j],p2[k]),C.r=C.c-p2[i];

            }
        }
        return C;
    }
}gmcc2;

struct Get_Min_Circle_Cover3
{
    Point circumcenter(const Point &a,const Point &b,const Point &c)
    {//返回三角形的外心 我并不知道这是什么鬼。。好强的样子。
        Point ret;
        double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;
        double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;
        double d=a1*b2-a2*b1;
        ret.x=a.x+(c1*b2-c2*b1)/d;
        ret.y=a.y+(a1*c2-a2*c1)/d;
        return ret;
    }
    Circle work(int n)
    {
        random_shuffle(p3+1,p3+n+1);
        Circle C=Circle(p3[1],0);
        int i,j,k;

        for(i=2;i<=n;i++)if(C^p3[i])
        {
            C=Circle(p3[i],0);
            for(j=1;j<i;j++)if(C^p3[j])
            {
                C.c=Point((p3[i].x+p3[j].x)/2,(p3[i].y+p3[j].y)/2);
                C.r=p3[j]-C.c;
                for(k=1;k<j;k++)if(C^p3[k])//求外接圆圆心,要求三点不能共线
                    C.c=circumcenter(p3[i],p3[j],p3[k]),C.r=C.c-p3[i];

            }
        }
        return C;
    }
}gmcc3;

int main()
{
//  freopen("test.in","r",stdin);

    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        double x,y,z;
        cin>>x>>y>>z;
        p1[i].x=x;
        p1[i].y=y;
        p2[i].x=y;
        p2[i].y=z;
        p3[i].x=x;
        p3[i].y=z;
    }
//  gch.work(p,n);
    Circle ret1=gmcc1.work(n);
    ret1.print();
    Circle ret2=gmcc2.work(n);
    ret2.print();
    Circle ret3=gmcc3.work(n);
    ret3.print();
    
    printf("%.10lf",min_r*2);

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值